| OLD | NEW |
| 1 //===- subzero/src/PNaClTranslator.cpp - ICE from bitcode -----------------===// | 1 //===- subzero/src/PNaClTranslator.cpp - ICE from bitcode -----------------===// |
| 2 // | 2 // |
| 3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
| 4 // | 4 // |
| 5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
| 7 // | 7 // |
| 8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
| 9 /// | 9 /// |
| 10 /// \file | 10 /// \file |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 214 return; | 214 return; |
| 215 | 215 |
| 216 // Mask out the high bits. | 216 // Mask out the high bits. |
| 217 Val &= ~static_cast<uint64_t>(0) >> (BITS_PER_WORD - BitWidth); | 217 Val &= ~static_cast<uint64_t>(0) >> (BITS_PER_WORD - BitWidth); |
| 218 } | 218 } |
| 219 }; | 219 }; |
| 220 | 220 |
| 221 class BlockParserBaseClass; | 221 class BlockParserBaseClass; |
| 222 | 222 |
| 223 // Top-level class to read PNaCl bitcode files, and translate to ICE. | 223 // Top-level class to read PNaCl bitcode files, and translate to ICE. |
| 224 class TopLevelParser : public NaClBitcodeParser { | 224 class TopLevelParser final : public NaClBitcodeParser { |
| 225 TopLevelParser() = delete; | 225 TopLevelParser() = delete; |
| 226 TopLevelParser(const TopLevelParser &) = delete; | 226 TopLevelParser(const TopLevelParser &) = delete; |
| 227 TopLevelParser &operator=(const TopLevelParser &) = delete; | 227 TopLevelParser &operator=(const TopLevelParser &) = delete; |
| 228 | 228 |
| 229 public: | 229 public: |
| 230 TopLevelParser(Ice::Translator &Translator, NaClBitstreamCursor &Cursor, | 230 TopLevelParser(Ice::Translator &Translator, NaClBitstreamCursor &Cursor, |
| 231 Ice::ErrorCode &ErrorStatus) | 231 Ice::ErrorCode &ErrorStatus) |
| 232 : NaClBitcodeParser(Cursor), Translator(Translator), | 232 : NaClBitcodeParser(Cursor), Translator(Translator), |
| 233 ErrorStatus(ErrorStatus), | 233 ErrorStatus(ErrorStatus), |
| 234 VariableDeclarations(new Ice::VariableDeclarationList()) {} | 234 VariableDeclarations(new Ice::VariableDeclarationList()) {} |
| 235 | 235 |
| 236 ~TopLevelParser() override = default; | 236 ~TopLevelParser() override = default; |
| 237 | 237 |
| 238 Ice::Translator &getTranslator() const { return Translator; } | 238 Ice::Translator &getTranslator() const { return Translator; } |
| 239 | 239 |
| 240 void setBlockParser(BlockParserBaseClass *NewBlockParser) { | |
| 241 BlockParser = NewBlockParser; | |
| 242 } | |
| 243 | |
| 244 /// Generates error with given Message, occurring at BitPosition within the | 240 /// Generates error with given Message, occurring at BitPosition within the |
| 245 /// bitcode file. Always returns true. | 241 /// bitcode file. Always returns true. |
| 246 bool ErrorAt(naclbitc::ErrorLevel Level, uint64_t BitPosition, | 242 bool ErrorAt(naclbitc::ErrorLevel Level, uint64_t BitPosition, |
| 247 const std::string &Message) final; | 243 const std::string &Message) override; |
| 248 | 244 |
| 249 /// Generates error message with respect to the current block parser. | 245 /// Generates error message with respect to the current block parser. |
| 250 bool blockError(const std::string &Message); | 246 bool blockError(const std::string &Message); |
| 251 | 247 |
| 252 /// Returns the number of errors found while parsing the bitcode file. | |
| 253 unsigned getNumErrors() const { return NumErrors; } | |
| 254 | |
| 255 /// Changes the size of the type list to the given size. | 248 /// Changes the size of the type list to the given size. |
| 256 void resizeTypeIDValues(size_t NewSize) { TypeIDValues.resize(NewSize); } | 249 void resizeTypeIDValues(size_t NewSize) { TypeIDValues.resize(NewSize); } |
| 257 | 250 |
| 258 size_t getNumTypeIDValues() const { return TypeIDValues.size(); } | 251 size_t getNumTypeIDValues() const { return TypeIDValues.size(); } |
| 259 | 252 |
| 260 /// Returns a pointer to the pool where globals are allocated. | 253 /// Returns a pointer to the pool where globals are allocated. |
| 261 Ice::VariableDeclarationList *getGlobalVariablesPool() { | 254 Ice::VariableDeclarationList *getGlobalVariablesPool() { |
| 262 return VariableDeclarations.get(); | 255 return VariableDeclarations.get(); |
| 263 } | 256 } |
| 264 | 257 |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 421 StrBuf << Prefix << " alignment greater than 2**" << AlignPowerLimit | 414 StrBuf << Prefix << " alignment greater than 2**" << AlignPowerLimit |
| 422 << ". Found: 2**" << (AlignPower - 1); | 415 << ". Found: 2**" << (AlignPower - 1); |
| 423 Parser->Error(StrBuf.str()); | 416 Parser->Error(StrBuf.str()); |
| 424 // Error recover with value that is always acceptable. | 417 // Error recover with value that is always acceptable. |
| 425 return 1; | 418 return 1; |
| 426 } | 419 } |
| 427 | 420 |
| 428 private: | 421 private: |
| 429 // The translator associated with the parser. | 422 // The translator associated with the parser. |
| 430 Ice::Translator &Translator; | 423 Ice::Translator &Translator; |
| 424 |
| 425 // ErrorStatus should only be updated while this lock is locked. |
| 426 Ice::GlobalLockType ErrorReportingLock; |
| 431 // The exit status that should be set to true if an error occurs. | 427 // The exit status that should be set to true if an error occurs. |
| 432 Ice::ErrorCode &ErrorStatus; | 428 Ice::ErrorCode &ErrorStatus; |
| 433 // The number of errors reported. | 429 |
| 434 unsigned NumErrors = 0; | |
| 435 // The types associated with each type ID. | 430 // The types associated with each type ID. |
| 436 std::vector<ExtendedType> TypeIDValues; | 431 std::vector<ExtendedType> TypeIDValues; |
| 437 // The set of functions (prototype and defined). | 432 // The set of functions (prototype and defined). |
| 438 Ice::FunctionDeclarationList FunctionDeclarations; | 433 Ice::FunctionDeclarationList FunctionDeclarations; |
| 439 // The ID of the next possible defined function ID in FunctionDeclarations. | 434 // The ID of the next possible defined function ID in FunctionDeclarations. |
| 440 // FunctionDeclarations is filled first. It's the set of functions (either | 435 // FunctionDeclarations is filled first. It's the set of functions (either |
| 441 // defined or isproto). Then function definitions are encountered/parsed and | 436 // defined or isproto). Then function definitions are encountered/parsed and |
| 442 // NextDefiningFunctionID is incremented to track the next actually-defined | 437 // NextDefiningFunctionID is incremented to track the next actually-defined |
| 443 // function. | 438 // function. |
| 444 size_t NextDefiningFunctionID = 0; | 439 size_t NextDefiningFunctionID = 0; |
| 445 // The set of global variables. | 440 // The set of global variables. |
| 446 std::unique_ptr<Ice::VariableDeclarationList> VariableDeclarations; | 441 std::unique_ptr<Ice::VariableDeclarationList> VariableDeclarations; |
| 447 // Relocatable constants associated with global declarations. | 442 // Relocatable constants associated with global declarations. |
| 448 Ice::ConstantList ValueIDConstants; | 443 Ice::ConstantList ValueIDConstants; |
| 449 // Error recovery value to use when getFuncSigTypeByID fails. | 444 // Error recovery value to use when getFuncSigTypeByID fails. |
| 450 Ice::FuncSigType UndefinedFuncSigType; | 445 Ice::FuncSigType UndefinedFuncSigType; |
| 451 // The block parser currently being applied. Used for error reporting. | |
| 452 BlockParserBaseClass *BlockParser = nullptr; | |
| 453 // Defines if a module block has already been parsed. | 446 // Defines if a module block has already been parsed. |
| 454 bool ParsedModuleBlock = false; | 447 bool ParsedModuleBlock = false; |
| 455 | 448 |
| 456 bool ParseBlock(unsigned BlockID) override; | 449 bool ParseBlock(unsigned BlockID) override; |
| 457 | 450 |
| 458 // Gets extended type associated with the given index, assuming the extended | 451 // Gets extended type associated with the given index, assuming the extended |
| 459 // type is of the WantedKind. Generates error message if corresponding | 452 // type is of the WantedKind. Generates error message if corresponding |
| 460 // extended type of WantedKind can't be found, and returns nullptr. | 453 // extended type of WantedKind can't be found, and returns nullptr. |
| 461 ExtendedType *getTypeByIDAsKind(NaClBcIndexSize_t ID, | 454 ExtendedType *getTypeByIDAsKind(NaClBcIndexSize_t ID, |
| 462 ExtendedType::TypeKind WantedKind) { | 455 ExtendedType::TypeKind WantedKind) { |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 577 Ice::VariableDeclaration * | 570 Ice::VariableDeclaration * |
| 578 reportGetGlobalVariableByIDError(NaClBcIndexSize_t Index); | 571 reportGetGlobalVariableByIDError(NaClBcIndexSize_t Index); |
| 579 | 572 |
| 580 // Reports that there is no corresponding ICE type for LLVMTy, and returns | 573 // Reports that there is no corresponding ICE type for LLVMTy, and returns |
| 581 // Ice::IceType_void. | 574 // Ice::IceType_void. |
| 582 Ice::Type convertToIceTypeError(Type *LLVMTy); | 575 Ice::Type convertToIceTypeError(Type *LLVMTy); |
| 583 }; | 576 }; |
| 584 | 577 |
| 585 bool TopLevelParser::ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit, | 578 bool TopLevelParser::ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit, |
| 586 const std::string &Message) { | 579 const std::string &Message) { |
| 587 ErrorStatus.assign(Ice::EC_Bitcode); | |
| 588 ++NumErrors; | |
| 589 Ice::GlobalContext *Context = Translator.getContext(); | 580 Ice::GlobalContext *Context = Translator.getContext(); |
| 581 { |
| 582 std::unique_lock<Ice::GlobalLockType> _(ErrorReportingLock); |
| 583 ErrorStatus.assign(Ice::EC_Bitcode); |
| 584 } |
| 590 { // Lock while printing out error message. | 585 { // Lock while printing out error message. |
| 591 Ice::OstreamLocker L(Context); | 586 Ice::OstreamLocker L(Context); |
| 592 raw_ostream &OldErrStream = setErrStream(Context->getStrError()); | 587 raw_ostream &OldErrStream = setErrStream(Context->getStrError()); |
| 593 NaClBitcodeParser::ErrorAt(Level, Bit, Message); | 588 NaClBitcodeParser::ErrorAt(Level, Bit, Message); |
| 594 setErrStream(OldErrStream); | 589 setErrStream(OldErrStream); |
| 595 } | 590 } |
| 596 if (Level >= naclbitc::Error && | 591 if (Level >= naclbitc::Error && |
| 597 !Translator.getFlags().getAllowErrorRecovery()) | 592 !Translator.getFlags().getAllowErrorRecovery()) |
| 598 Fatal(); | 593 Fatal(); |
| 599 return true; | 594 return true; |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 658 // the base class of block parsers, we generate error messages if ParseBlock or | 653 // the base class of block parsers, we generate error messages if ParseBlock or |
| 659 // ParseRecord is not overridden in derived classes. | 654 // ParseRecord is not overridden in derived classes. |
| 660 class BlockParserBaseClass : public NaClBitcodeParser { | 655 class BlockParserBaseClass : public NaClBitcodeParser { |
| 661 BlockParserBaseClass() = delete; | 656 BlockParserBaseClass() = delete; |
| 662 BlockParserBaseClass(const BlockParserBaseClass &) = delete; | 657 BlockParserBaseClass(const BlockParserBaseClass &) = delete; |
| 663 BlockParserBaseClass &operator=(const BlockParserBaseClass &) = delete; | 658 BlockParserBaseClass &operator=(const BlockParserBaseClass &) = delete; |
| 664 | 659 |
| 665 public: | 660 public: |
| 666 // Constructor for the top-level module block parser. | 661 // Constructor for the top-level module block parser. |
| 667 BlockParserBaseClass(unsigned BlockID, TopLevelParser *Context) | 662 BlockParserBaseClass(unsigned BlockID, TopLevelParser *Context) |
| 668 : NaClBitcodeParser(BlockID, Context), Context(Context) { | 663 : NaClBitcodeParser(BlockID, Context), Context(Context) {} |
| 669 Context->setBlockParser(this); | |
| 670 } | |
| 671 | 664 |
| 672 ~BlockParserBaseClass() override { Context->setBlockParser(nullptr); } | 665 BlockParserBaseClass(unsigned BlockID, BlockParserBaseClass *EnclosingParser, |
| 666 NaClBitstreamCursor &Cursor) |
| 667 : NaClBitcodeParser(BlockID, EnclosingParser, Cursor), |
| 668 Context(EnclosingParser->Context) {} |
| 669 |
| 670 ~BlockParserBaseClass() override {} |
| 673 | 671 |
| 674 // Returns the printable name of the type of block being parsed. | 672 // Returns the printable name of the type of block being parsed. |
| 675 virtual const char *getBlockName() const { | 673 virtual const char *getBlockName() const { |
| 676 // If this class is used, it is parsing an unknown block. | 674 // If this class is used, it is parsing an unknown block. |
| 677 return "unknown"; | 675 return "unknown"; |
| 678 } | 676 } |
| 679 | 677 |
| 680 // Generates an error Message with the Bit address prefixed to it. | 678 // Generates an error Message with the Bit address prefixed to it. |
| 681 bool ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit, | 679 bool ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit, |
| 682 const std::string &Message) final; | 680 const std::string &Message) override; |
| 683 | 681 |
| 684 protected: | 682 protected: |
| 685 // The context parser that contains the decoded state. | 683 // The context parser that contains the decoded state. |
| 686 TopLevelParser *Context; | 684 TopLevelParser *Context; |
| 685 // True if ErrorAt has been called in this block. |
| 686 bool BlockHasError = false; |
| 687 | 687 |
| 688 // Constructor for nested block parsers. | 688 // Constructor for nested block parsers. |
| 689 BlockParserBaseClass(unsigned BlockID, BlockParserBaseClass *EnclosingParser) | 689 BlockParserBaseClass(unsigned BlockID, BlockParserBaseClass *EnclosingParser) |
| 690 : NaClBitcodeParser(BlockID, EnclosingParser), | 690 : NaClBitcodeParser(BlockID, EnclosingParser), |
| 691 Context(EnclosingParser->Context) {} | 691 Context(EnclosingParser->Context) {} |
| 692 | 692 |
| 693 // Gets the translator associated with the bitcode parser. | 693 // Gets the translator associated with the bitcode parser. |
| 694 Ice::Translator &getTranslator() const { return Context->getTranslator(); } | 694 Ice::Translator &getTranslator() const { return Context->getTranslator(); } |
| 695 | 695 |
| 696 const Ice::ClFlags &getFlags() const { return getTranslator().getFlags(); } | 696 const Ice::ClFlags &getFlags() const { return getTranslator().getFlags(); } |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 745 private: | 745 private: |
| 746 /// Generates a record size error. ExpectedSize is the number of elements | 746 /// Generates a record size error. ExpectedSize is the number of elements |
| 747 /// expected. RecordName is the name of the kind of record that has incorrect | 747 /// expected. RecordName is the name of the kind of record that has incorrect |
| 748 /// size. ContextMessage (if not nullptr) is appended to "record expects" to | 748 /// size. ContextMessage (if not nullptr) is appended to "record expects" to |
| 749 /// describe how ExpectedSize should be interpreted. | 749 /// describe how ExpectedSize should be interpreted. |
| 750 void reportRecordSizeError(size_t ExpectedSize, const char *RecordName, | 750 void reportRecordSizeError(size_t ExpectedSize, const char *RecordName, |
| 751 const char *ContextMessage); | 751 const char *ContextMessage); |
| 752 }; | 752 }; |
| 753 | 753 |
| 754 bool TopLevelParser::blockError(const std::string &Message) { | 754 bool TopLevelParser::blockError(const std::string &Message) { |
| 755 if (BlockParser) | 755 // TODO(kschimpf): Remove this method. This method used to redirect |
| 756 return BlockParser->Error(Message); | 756 // block-level errors to the block we are in, rather than the top-level |
| 757 else | 757 // block. This gave better bit location for error messages. However, with |
| 758 return Error(Message); | 758 // parallel parsing, we can't keep a field to redirect (there could be many |
| 759 // and we don't know which block parser applies). Hence, This redirect can't |
| 760 // be applied anymore. |
| 761 return Error(Message); |
| 759 } | 762 } |
| 760 | 763 |
| 761 // Generates an error Message with the bit address prefixed to it. | 764 // Generates an error Message with the bit address prefixed to it. |
| 762 bool BlockParserBaseClass::ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit, | 765 bool BlockParserBaseClass::ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit, |
| 763 const std::string &Message) { | 766 const std::string &Message) { |
| 767 BlockHasError = true; |
| 764 std::string Buffer; | 768 std::string Buffer; |
| 765 raw_string_ostream StrBuf(Buffer); | 769 raw_string_ostream StrBuf(Buffer); |
| 766 // Note: If dump routines have been turned off, the error messages will not | 770 // Note: If dump routines have been turned off, the error messages will not |
| 767 // be readable. Hence, replace with simple error. We also use the simple form | 771 // be readable. Hence, replace with simple error. We also use the simple form |
| 768 // for unit tests. | 772 // for unit tests. |
| 769 if (getFlags().getGenerateUnitTestMessages()) { | 773 if (getFlags().getGenerateUnitTestMessages()) { |
| 770 StrBuf << "Invalid " << getBlockName() << " record: <" << Record.GetCode(); | 774 StrBuf << "Invalid " << getBlockName() << " record: <" << Record.GetCode(); |
| 771 for (const uint64_t Val : Record.GetValues()) { | 775 for (const uint64_t Val : Record.GetValues()) { |
| 772 StrBuf << " " << Val; | 776 StrBuf << " " << Val; |
| 773 } | 777 } |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 810 void BlockParserBaseClass::ProcessRecord() { | 814 void BlockParserBaseClass::ProcessRecord() { |
| 811 // If called, derived class doesn't know how to handle. | 815 // If called, derived class doesn't know how to handle. |
| 812 std::string Buffer; | 816 std::string Buffer; |
| 813 raw_string_ostream StrBuf(Buffer); | 817 raw_string_ostream StrBuf(Buffer); |
| 814 StrBuf << "Don't know how to process " << getBlockName() | 818 StrBuf << "Don't know how to process " << getBlockName() |
| 815 << " record:" << Record; | 819 << " record:" << Record; |
| 816 Error(StrBuf.str()); | 820 Error(StrBuf.str()); |
| 817 } | 821 } |
| 818 | 822 |
| 819 // Class to parse a types block. | 823 // Class to parse a types block. |
| 820 class TypesParser : public BlockParserBaseClass { | 824 class TypesParser final : public BlockParserBaseClass { |
| 821 TypesParser() = delete; | 825 TypesParser() = delete; |
| 822 TypesParser(const TypesParser &) = delete; | 826 TypesParser(const TypesParser &) = delete; |
| 823 TypesParser &operator=(const TypesParser &) = delete; | 827 TypesParser &operator=(const TypesParser &) = delete; |
| 824 | 828 |
| 825 public: | 829 public: |
| 826 TypesParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) | 830 TypesParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) |
| 827 : BlockParserBaseClass(BlockID, EnclosingParser), | 831 : BlockParserBaseClass(BlockID, EnclosingParser), |
| 828 Timer(Ice::TimerStack::TT_parseTypes, getTranslator().getContext()) {} | 832 Timer(Ice::TimerStack::TT_parseTypes, getTranslator().getContext()) {} |
| 829 | 833 |
| 830 ~TypesParser() override { | 834 ~TypesParser() override { |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1014 } | 1018 } |
| 1015 default: | 1019 default: |
| 1016 BlockParserBaseClass::ProcessRecord(); | 1020 BlockParserBaseClass::ProcessRecord(); |
| 1017 return; | 1021 return; |
| 1018 } | 1022 } |
| 1019 llvm_unreachable("Unknown type block record not processed!"); | 1023 llvm_unreachable("Unknown type block record not processed!"); |
| 1020 } | 1024 } |
| 1021 | 1025 |
| 1022 /// Parses the globals block (i.e. global variable declarations and | 1026 /// Parses the globals block (i.e. global variable declarations and |
| 1023 /// corresponding initializers). | 1027 /// corresponding initializers). |
| 1024 class GlobalsParser : public BlockParserBaseClass { | 1028 class GlobalsParser final : public BlockParserBaseClass { |
| 1025 GlobalsParser() = delete; | 1029 GlobalsParser() = delete; |
| 1026 GlobalsParser(const GlobalsParser &) = delete; | 1030 GlobalsParser(const GlobalsParser &) = delete; |
| 1027 GlobalsParser &operator=(const GlobalsParser &) = delete; | 1031 GlobalsParser &operator=(const GlobalsParser &) = delete; |
| 1028 | 1032 |
| 1029 public: | 1033 public: |
| 1030 GlobalsParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) | 1034 GlobalsParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) |
| 1031 : BlockParserBaseClass(BlockID, EnclosingParser), | 1035 : BlockParserBaseClass(BlockID, EnclosingParser), |
| 1032 Timer(Ice::TimerStack::TT_parseGlobals, getTranslator().getContext()), | 1036 Timer(Ice::TimerStack::TT_parseGlobals, getTranslator().getContext()), |
| 1033 NumFunctionIDs(Context->getNumFunctionIDs()), | 1037 NumFunctionIDs(Context->getNumFunctionIDs()), |
| 1034 DummyGlobalVar(Ice::VariableDeclaration::create( | 1038 DummyGlobalVar(Ice::VariableDeclaration::create( |
| 1035 Context->getGlobalVariablesPool())), | 1039 Context->getGlobalVariablesPool())), |
| 1036 CurGlobalVar(DummyGlobalVar) { | 1040 CurGlobalVar(DummyGlobalVar) { |
| 1037 Context->getGlobalVariablesPool()->willNotBeEmitted(DummyGlobalVar); | 1041 Context->getGlobalVariablesPool()->willNotBeEmitted(DummyGlobalVar); |
| 1038 } | 1042 } |
| 1039 | 1043 |
| 1040 ~GlobalsParser() final = default; | 1044 ~GlobalsParser() override = default; |
| 1041 | 1045 |
| 1042 const char *getBlockName() const override { return "globals"; } | 1046 const char *getBlockName() const override { return "globals"; } |
| 1043 | 1047 |
| 1044 private: | 1048 private: |
| 1045 using GlobalVarsMapType = | 1049 using GlobalVarsMapType = |
| 1046 std::unordered_map<NaClBcIndexSize_t, Ice::VariableDeclaration *>; | 1050 std::unordered_map<NaClBcIndexSize_t, Ice::VariableDeclaration *>; |
| 1047 | 1051 |
| 1048 Ice::TimerMarker Timer; | 1052 Ice::TimerMarker Timer; |
| 1049 | 1053 |
| 1050 // Holds global variables generated/referenced in the global variables block. | 1054 // Holds global variables generated/referenced in the global variables block. |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1334 } | 1338 } |
| 1335 default: | 1339 default: |
| 1336 break; | 1340 break; |
| 1337 } | 1341 } |
| 1338 // If reached, don't know how to handle record. | 1342 // If reached, don't know how to handle record. |
| 1339 BlockParserBaseClass::ProcessRecord(); | 1343 BlockParserBaseClass::ProcessRecord(); |
| 1340 return; | 1344 return; |
| 1341 } | 1345 } |
| 1342 | 1346 |
| 1343 /// Parses function blocks in the bitcode file. | 1347 /// Parses function blocks in the bitcode file. |
| 1344 class FunctionParser : public BlockParserBaseClass { | 1348 class FunctionParser final : public BlockParserBaseClass { |
| 1345 FunctionParser() = delete; | 1349 FunctionParser() = delete; |
| 1346 FunctionParser(const FunctionParser &) = delete; | 1350 FunctionParser(const FunctionParser &) = delete; |
| 1347 FunctionParser &operator=(const FunctionParser &) = delete; | 1351 FunctionParser &operator=(const FunctionParser &) = delete; |
| 1348 | 1352 |
| 1349 public: | 1353 public: |
| 1350 FunctionParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) | 1354 FunctionParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser, |
| 1355 NaClBcIndexSize_t FcnId) |
| 1351 : BlockParserBaseClass(BlockID, EnclosingParser), | 1356 : BlockParserBaseClass(BlockID, EnclosingParser), |
| 1352 Timer(Ice::TimerStack::TT_parseFunctions, getTranslator().getContext()), | 1357 Timer(Ice::TimerStack::TT_parseFunctions, getTranslator().getContext()), |
| 1353 Func(nullptr), FcnId(Context->getNextFunctionBlockValueID()), | 1358 Func(nullptr), FuncDecl(Context->getFunctionByID(FcnId)), |
| 1354 FuncDecl(Context->getFunctionByID(FcnId)), | |
| 1355 CachedNumGlobalValueIDs(Context->getNumGlobalIDs()), | 1359 CachedNumGlobalValueIDs(Context->getNumGlobalIDs()), |
| 1356 NextLocalInstIndex(Context->getNumGlobalIDs()) {} | 1360 NextLocalInstIndex(Context->getNumGlobalIDs()) {} |
| 1357 | 1361 |
| 1358 bool convertFunction() { | 1362 FunctionParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser, |
| 1363 NaClBcIndexSize_t FcnId, NaClBitstreamCursor &Cursor) |
| 1364 : BlockParserBaseClass(BlockID, EnclosingParser, Cursor), |
| 1365 Timer(Ice::TimerStack::TT_parseFunctions, getTranslator().getContext()), |
| 1366 Func(nullptr), FuncDecl(Context->getFunctionByID(FcnId)), |
| 1367 CachedNumGlobalValueIDs(Context->getNumGlobalIDs()), |
| 1368 NextLocalInstIndex(Context->getNumGlobalIDs()) {} |
| 1369 |
| 1370 std::unique_ptr<Ice::Cfg> parseFunction(uint32_t SeqNumber) { |
| 1359 bool ParserResult; | 1371 bool ParserResult; |
| 1372 Ice::GlobalContext *Ctx = getTranslator().getContext(); |
| 1360 { | 1373 { |
| 1361 Ice::TimerMarker T(getTranslator().getContext(), | 1374 Ice::TimerMarker T(Ctx, FuncDecl->getName().toStringOrEmpty()); |
| 1362 FuncDecl->getName().toStringOrEmpty()); | |
| 1363 // Note: The Cfg is created, even when IR generation is disabled. This is | 1375 // Note: The Cfg is created, even when IR generation is disabled. This is |
| 1364 // done to install a CfgLocalAllocator for various internal containers. | 1376 // done to install a CfgLocalAllocator for various internal containers. |
| 1365 Ice::GlobalContext *Ctx = getTranslator().getContext(); | 1377 Ice::GlobalContext *Ctx = getTranslator().getContext(); |
| 1366 Func = Ice::Cfg::create(Ctx, getTranslator().getNextSequenceNumber()); | 1378 Func = Ice::Cfg::create(Ctx, SeqNumber); |
| 1367 | 1379 |
| 1368 Ice::CfgLocalAllocatorScope _(Func.get()); | 1380 Ice::CfgLocalAllocatorScope _(Func.get()); |
| 1369 | 1381 |
| 1370 // TODO(kschimpf) Clean up API to add a function signature to a CFG. | 1382 // TODO(kschimpf) Clean up API to add a function signature to a CFG. |
| 1371 const Ice::FuncSigType &Signature = FuncDecl->getSignature(); | 1383 const Ice::FuncSigType &Signature = FuncDecl->getSignature(); |
| 1372 | 1384 |
| 1373 Func->setFunctionName(FuncDecl->getName()); | 1385 Func->setFunctionName(FuncDecl->getName()); |
| 1374 Func->setReturnType(Signature.getReturnType()); | 1386 Func->setReturnType(Signature.getReturnType()); |
| 1375 Func->setInternal(FuncDecl->getLinkage() == GlobalValue::InternalLinkage); | 1387 Func->setInternal(FuncDecl->getLinkage() == GlobalValue::InternalLinkage); |
| 1376 CurrentNode = installNextBasicBlock(); | 1388 CurrentNode = installNextBasicBlock(); |
| 1377 Func->setEntryNode(CurrentNode); | 1389 Func->setEntryNode(CurrentNode); |
| 1378 for (Ice::Type ArgType : Signature.getArgList()) { | 1390 for (Ice::Type ArgType : Signature.getArgList()) { |
| 1379 Func->addArg(getNextInstVar(ArgType)); | 1391 Func->addArg(getNextInstVar(ArgType)); |
| 1380 } | 1392 } |
| 1381 | 1393 |
| 1382 ParserResult = ParseThisBlock(); | 1394 ParserResult = ParseThisBlock(); |
| 1383 | |
| 1384 // Note: Once any errors have been found, we turn off all translation of | |
| 1385 // all remaining functions. This allows successive parsing errors to be | |
| 1386 // reported, without adding extra checks to the translator for such | |
| 1387 // parsing errors. | |
| 1388 } | |
| 1389 if (Context->getNumErrors() == 0 && Func) { | |
| 1390 getTranslator().translateFcn(std::move(Func)); | |
| 1391 // The translator now has ownership of Func. | |
| 1392 } else { | |
| 1393 Func.reset(); | |
| 1394 } | 1395 } |
| 1395 | 1396 |
| 1396 return ParserResult; | 1397 if (ParserResult || BlockHasError) |
| 1398 Func->setError("Unable to parse function"); |
| 1399 |
| 1400 return std::move(Func); |
| 1397 } | 1401 } |
| 1398 | 1402 |
| 1399 ~FunctionParser() final = default; | 1403 ~FunctionParser() override = default; |
| 1400 | 1404 |
| 1401 const char *getBlockName() const override { return "function"; } | 1405 const char *getBlockName() const override { return "function"; } |
| 1402 | 1406 |
| 1403 Ice::Cfg *getFunc() const { return Func.get(); } | 1407 Ice::Cfg *getFunc() const { return Func.get(); } |
| 1404 | 1408 |
| 1405 size_t getNumGlobalIDs() const { return CachedNumGlobalValueIDs; } | 1409 size_t getNumGlobalIDs() const { return CachedNumGlobalValueIDs; } |
| 1406 | 1410 |
| 1407 void setNextLocalInstIndex(Ice::Operand *Op) { | 1411 void setNextLocalInstIndex(Ice::Operand *Op) { |
| 1408 setOperand(NextLocalInstIndex++, Op); | 1412 setOperand(NextLocalInstIndex++, Op); |
| 1409 } | 1413 } |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1433 // the number of bytes defining the function block. | 1437 // the number of bytes defining the function block. |
| 1434 uint64_t MaxRecordsInBlock = 0; | 1438 uint64_t MaxRecordsInBlock = 0; |
| 1435 // The corresponding ICE function defined by the function block. | 1439 // The corresponding ICE function defined by the function block. |
| 1436 std::unique_ptr<Ice::Cfg> Func; | 1440 std::unique_ptr<Ice::Cfg> Func; |
| 1437 // The index to the current basic block being built. | 1441 // The index to the current basic block being built. |
| 1438 NaClBcIndexSize_t CurrentBbIndex = 0; | 1442 NaClBcIndexSize_t CurrentBbIndex = 0; |
| 1439 // The number of basic blocks declared for the function block. | 1443 // The number of basic blocks declared for the function block. |
| 1440 NaClBcIndexSize_t DeclaredNumberBbs = 0; | 1444 NaClBcIndexSize_t DeclaredNumberBbs = 0; |
| 1441 // The basic block being built. | 1445 // The basic block being built. |
| 1442 Ice::CfgNode *CurrentNode = nullptr; | 1446 Ice::CfgNode *CurrentNode = nullptr; |
| 1443 // The ID for the function. | |
| 1444 NaClBcIndexSize_t FcnId; | |
| 1445 // The corresponding function declaration. | 1447 // The corresponding function declaration. |
| 1446 Ice::FunctionDeclaration *FuncDecl; | 1448 Ice::FunctionDeclaration *FuncDecl; |
| 1447 // Holds the dividing point between local and global absolute value indices. | 1449 // Holds the dividing point between local and global absolute value indices. |
| 1448 size_t CachedNumGlobalValueIDs; | 1450 size_t CachedNumGlobalValueIDs; |
| 1449 // Holds operands local to the function block, based on indices defined in | 1451 // Holds operands local to the function block, based on indices defined in |
| 1450 // the bitcode file. | 1452 // the bitcode file. |
| 1451 Ice::OperandList LocalOperands; | 1453 Ice::OperandList LocalOperands; |
| 1452 // Holds the index within LocalOperands corresponding to the next instruction | 1454 // Holds the index within LocalOperands corresponding to the next instruction |
| 1453 // that generates a value. | 1455 // that generates a value. |
| 1454 NaClBcIndexSize_t NextLocalInstIndex; | 1456 NaClBcIndexSize_t NextLocalInstIndex; |
| 1455 // True if the last processed instruction was a terminating instruction. | 1457 // True if the last processed instruction was a terminating instruction. |
| 1456 bool InstIsTerminating = false; | 1458 bool InstIsTerminating = false; |
| 1457 | 1459 |
| 1458 bool ParseBlock(unsigned BlockID) override; | 1460 bool ParseBlock(unsigned BlockID) override; |
| 1459 | 1461 |
| 1460 void ProcessRecord() override; | 1462 void ProcessRecord() override; |
| 1461 | 1463 |
| 1462 void EnterBlock(unsigned NumWords) final { | 1464 void EnterBlock(unsigned NumWords) override { |
| 1463 // Note: Bitstream defines words as 32-bit values. | 1465 // Note: Bitstream defines words as 32-bit values. |
| 1464 NumBytesDefiningFunction = NumWords * sizeof(uint32_t); | 1466 NumBytesDefiningFunction = NumWords * sizeof(uint32_t); |
| 1465 // We know that all records are minimally defined by a two-bit abreviation. | 1467 // We know that all records are minimally defined by a two-bit abreviation. |
| 1466 MaxRecordsInBlock = NumBytesDefiningFunction * (CHAR_BIT >> 1); | 1468 MaxRecordsInBlock = NumBytesDefiningFunction * (CHAR_BIT >> 1); |
| 1467 } | 1469 } |
| 1468 | 1470 |
| 1469 void ExitBlock() override; | 1471 void ExitBlock() override; |
| 1470 | 1472 |
| 1471 // Creates and appends a new basic block to the list of basic blocks. | 1473 // Creates and appends a new basic block to the list of basic blocks. |
| 1472 Ice::CfgNode *installNextBasicBlock() { | 1474 Ice::CfgNode *installNextBasicBlock() { |
| (...skipping 1300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2773 return; | 2775 return; |
| 2774 } | 2776 } |
| 2775 default: | 2777 default: |
| 2776 // Generate error message! | 2778 // Generate error message! |
| 2777 BlockParserBaseClass::ProcessRecord(); | 2779 BlockParserBaseClass::ProcessRecord(); |
| 2778 return; | 2780 return; |
| 2779 } | 2781 } |
| 2780 } | 2782 } |
| 2781 | 2783 |
| 2782 /// Parses constants within a function block. | 2784 /// Parses constants within a function block. |
| 2783 class ConstantsParser : public BlockParserBaseClass { | 2785 class ConstantsParser final : public BlockParserBaseClass { |
| 2784 ConstantsParser() = delete; | 2786 ConstantsParser() = delete; |
| 2785 ConstantsParser(const ConstantsParser &) = delete; | 2787 ConstantsParser(const ConstantsParser &) = delete; |
| 2786 ConstantsParser &operator=(const ConstantsParser &) = delete; | 2788 ConstantsParser &operator=(const ConstantsParser &) = delete; |
| 2787 | 2789 |
| 2788 public: | 2790 public: |
| 2789 ConstantsParser(unsigned BlockID, FunctionParser *FuncParser) | 2791 ConstantsParser(unsigned BlockID, FunctionParser *FuncParser) |
| 2790 : BlockParserBaseClass(BlockID, FuncParser), | 2792 : BlockParserBaseClass(BlockID, FuncParser), |
| 2791 Timer(Ice::TimerStack::TT_parseConstants, getTranslator().getContext()), | 2793 Timer(Ice::TimerStack::TT_parseConstants, getTranslator().getContext()), |
| 2792 FuncParser(FuncParser) {} | 2794 FuncParser(FuncParser) {} |
| 2793 | 2795 |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2890 } | 2892 } |
| 2891 } | 2893 } |
| 2892 default: | 2894 default: |
| 2893 // Generate error message! | 2895 // Generate error message! |
| 2894 BlockParserBaseClass::ProcessRecord(); | 2896 BlockParserBaseClass::ProcessRecord(); |
| 2895 return; | 2897 return; |
| 2896 } | 2898 } |
| 2897 } | 2899 } |
| 2898 | 2900 |
| 2899 // Parses valuesymtab blocks appearing in a function block. | 2901 // Parses valuesymtab blocks appearing in a function block. |
| 2900 class FunctionValuesymtabParser : public ValuesymtabParser { | 2902 class FunctionValuesymtabParser final : public ValuesymtabParser { |
| 2901 FunctionValuesymtabParser() = delete; | 2903 FunctionValuesymtabParser() = delete; |
| 2902 FunctionValuesymtabParser(const FunctionValuesymtabParser &) = delete; | 2904 FunctionValuesymtabParser(const FunctionValuesymtabParser &) = delete; |
| 2903 void operator=(const FunctionValuesymtabParser &) = delete; | 2905 void operator=(const FunctionValuesymtabParser &) = delete; |
| 2904 | 2906 |
| 2905 public: | 2907 public: |
| 2906 FunctionValuesymtabParser(unsigned BlockID, FunctionParser *EnclosingParser) | 2908 FunctionValuesymtabParser(unsigned BlockID, FunctionParser *EnclosingParser) |
| 2907 : ValuesymtabParser(BlockID, EnclosingParser), | 2909 : ValuesymtabParser(BlockID, EnclosingParser), |
| 2908 Timer(Ice::TimerStack::TT_parseFunctionValuesymtabs, | 2910 Timer(Ice::TimerStack::TT_parseFunctionValuesymtabs, |
| 2909 getTranslator().getContext()) {} | 2911 getTranslator().getContext()) {} |
| 2910 | 2912 |
| 2911 private: | 2913 private: |
| 2912 Ice::TimerMarker Timer; | 2914 Ice::TimerMarker Timer; |
| 2913 // Returns the enclosing function parser. | 2915 // Returns the enclosing function parser. |
| 2914 FunctionParser *getFunctionParser() const { | 2916 FunctionParser *getFunctionParser() const { |
| 2915 return reinterpret_cast<FunctionParser *>(GetEnclosingParser()); | 2917 return reinterpret_cast<FunctionParser *>(GetEnclosingParser()); |
| 2916 } | 2918 } |
| 2917 | 2919 |
| 2918 const char *getTableKind() const final { return "Function"; } | 2920 const char *getTableKind() const override { return "Function"; } |
| 2919 | 2921 |
| 2920 void setValueName(NaClBcIndexSize_t Index, StringType &Name) final; | 2922 void setValueName(NaClBcIndexSize_t Index, StringType &Name) override; |
| 2921 void setBbName(NaClBcIndexSize_t Index, StringType &Name) final; | 2923 void setBbName(NaClBcIndexSize_t Index, StringType &Name) override; |
| 2922 | 2924 |
| 2923 // Reports that the assignment of Name to the value associated with index is | 2925 // Reports that the assignment of Name to the value associated with index is |
| 2924 // not possible, for the given Context. | 2926 // not possible, for the given Context. |
| 2925 void reportUnableToAssign(const char *Context, NaClBcIndexSize_t Index, | 2927 void reportUnableToAssign(const char *Context, NaClBcIndexSize_t Index, |
| 2926 StringType &Name) { | 2928 StringType &Name) { |
| 2927 std::string Buffer; | 2929 std::string Buffer; |
| 2928 raw_string_ostream StrBuf(Buffer); | 2930 raw_string_ostream StrBuf(Buffer); |
| 2929 StrBuf << "Function-local " << Context << " name '" << Name | 2931 StrBuf << "Function-local " << Context << " name '" << Name |
| 2930 << "' can't be associated with index " << Index; | 2932 << "' can't be associated with index " << Index; |
| 2931 Error(StrBuf.str()); | 2933 Error(StrBuf.str()); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2977 } | 2979 } |
| 2978 break; | 2980 break; |
| 2979 } | 2981 } |
| 2980 default: | 2982 default: |
| 2981 break; | 2983 break; |
| 2982 } | 2984 } |
| 2983 return BlockParserBaseClass::ParseBlock(BlockID); | 2985 return BlockParserBaseClass::ParseBlock(BlockID); |
| 2984 } | 2986 } |
| 2985 | 2987 |
| 2986 /// Parses the module block in the bitcode file. | 2988 /// Parses the module block in the bitcode file. |
| 2987 class ModuleParser : public BlockParserBaseClass { | 2989 class ModuleParser final : public BlockParserBaseClass { |
| 2988 ModuleParser() = delete; | 2990 ModuleParser() = delete; |
| 2989 ModuleParser(const ModuleParser &) = delete; | 2991 ModuleParser(const ModuleParser &) = delete; |
| 2990 ModuleParser &operator=(const ModuleParser &) = delete; | 2992 ModuleParser &operator=(const ModuleParser &) = delete; |
| 2991 | 2993 |
| 2992 public: | 2994 public: |
| 2993 ModuleParser(unsigned BlockID, TopLevelParser *Context) | 2995 ModuleParser(unsigned BlockID, TopLevelParser *Context) |
| 2994 : BlockParserBaseClass(BlockID, Context), | 2996 : BlockParserBaseClass(BlockID, Context), |
| 2995 Timer(Ice::TimerStack::TT_parseModule, | 2997 Timer(Ice::TimerStack::TT_parseModule, |
| 2996 Context->getTranslator().getContext()) {} | 2998 Context->getTranslator().getContext()) {} |
| 2997 | |
| 2998 ~ModuleParser() override = default; | 2999 ~ModuleParser() override = default; |
| 2999 | |
| 3000 const char *getBlockName() const override { return "module"; } | 3000 const char *getBlockName() const override { return "module"; } |
| 3001 NaClBitstreamCursor &getCursor() const { return Record.GetCursor(); } |
| 3001 | 3002 |
| 3002 private: | 3003 private: |
| 3003 Ice::TimerMarker Timer; | 3004 Ice::TimerMarker Timer; |
| 3004 // True if we have already installed names for unnamed global declarations, | 3005 // True if we have already installed names for unnamed global declarations, |
| 3005 // and have generated global constant initializers. | 3006 // and have generated global constant initializers. |
| 3006 bool GlobalDeclarationNamesAndInitializersInstalled = false; | 3007 bool GlobalDeclarationNamesAndInitializersInstalled = false; |
| 3007 // True if we have already processed the symbol table for the module. | 3008 // True if we have already processed the symbol table for the module. |
| 3008 bool FoundValuesymtab = false; | 3009 bool FoundValuesymtab = false; |
| 3009 | 3010 |
| 3010 // Generates names for unnamed global addresses (i.e. functions and global | 3011 // Generates names for unnamed global addresses (i.e. functions and global |
| 3011 // variables). Then lowers global variable declaration initializers to the | 3012 // variables). Then lowers global variable declaration initializers to the |
| 3012 // target. May be called multiple times. Only the first call will do the | 3013 // target. May be called multiple times. Only the first call will do the |
| 3013 // installation. | 3014 // installation. |
| 3014 void installGlobalNamesAndGlobalVarInitializers() { | 3015 void installGlobalNamesAndGlobalVarInitializers() { |
| 3015 if (!GlobalDeclarationNamesAndInitializersInstalled) { | 3016 if (!GlobalDeclarationNamesAndInitializersInstalled) { |
| 3016 Context->installGlobalNames(); | 3017 Context->installGlobalNames(); |
| 3017 Context->createValueIDs(); | 3018 Context->createValueIDs(); |
| 3018 Context->verifyFunctionTypeSignatures(); | 3019 Context->verifyFunctionTypeSignatures(); |
| 3019 std::unique_ptr<Ice::VariableDeclarationList> Globals = | 3020 std::unique_ptr<Ice::VariableDeclarationList> Globals = |
| 3020 Context->getGlobalVariables(); | 3021 Context->getGlobalVariables(); |
| 3021 if (Globals) | 3022 if (Globals) |
| 3022 getTranslator().lowerGlobals(std::move(Globals)); | 3023 getTranslator().lowerGlobals(std::move(Globals)); |
| 3023 GlobalDeclarationNamesAndInitializersInstalled = true; | 3024 GlobalDeclarationNamesAndInitializersInstalled = true; |
| 3024 } | 3025 } |
| 3025 } | 3026 } |
| 3026 bool ParseBlock(unsigned BlockID) override; | 3027 bool ParseBlock(unsigned BlockID) override; |
| 3027 | 3028 |
| 3028 void ExitBlock() override { installGlobalNamesAndGlobalVarInitializers(); } | 3029 void ExitBlock() override { |
| 3030 installGlobalNamesAndGlobalVarInitializers(); |
| 3031 Context->getTranslator().getContext()->waitForWorkerThreads(); |
| 3032 } |
| 3029 | 3033 |
| 3030 void ProcessRecord() override; | 3034 void ProcessRecord() override; |
| 3031 }; | 3035 }; |
| 3032 | 3036 |
| 3033 class ModuleValuesymtabParser : public ValuesymtabParser { | 3037 class ModuleValuesymtabParser : public ValuesymtabParser { |
| 3034 ModuleValuesymtabParser() = delete; | 3038 ModuleValuesymtabParser() = delete; |
| 3035 ModuleValuesymtabParser(const ModuleValuesymtabParser &) = delete; | 3039 ModuleValuesymtabParser(const ModuleValuesymtabParser &) = delete; |
| 3036 void operator=(const ModuleValuesymtabParser &) = delete; | 3040 void operator=(const ModuleValuesymtabParser &) = delete; |
| 3037 | 3041 |
| 3038 public: | 3042 public: |
| 3039 ModuleValuesymtabParser(unsigned BlockID, ModuleParser *MP) | 3043 ModuleValuesymtabParser(unsigned BlockID, ModuleParser *MP) |
| 3040 : ValuesymtabParser(BlockID, MP), | 3044 : ValuesymtabParser(BlockID, MP), |
| 3041 Timer(Ice::TimerStack::TT_parseModuleValuesymtabs, | 3045 Timer(Ice::TimerStack::TT_parseModuleValuesymtabs, |
| 3042 getTranslator().getContext()) {} | 3046 getTranslator().getContext()) {} |
| 3043 | 3047 |
| 3044 ~ModuleValuesymtabParser() override = default; | 3048 ~ModuleValuesymtabParser() override = default; |
| 3045 | 3049 |
| 3046 private: | 3050 private: |
| 3047 Ice::TimerMarker Timer; | 3051 Ice::TimerMarker Timer; |
| 3048 const char *getTableKind() const final { return "Module"; } | 3052 const char *getTableKind() const override { return "Module"; } |
| 3049 void setValueName(NaClBcIndexSize_t Index, StringType &Name) final; | 3053 void setValueName(NaClBcIndexSize_t Index, StringType &Name) override; |
| 3050 void setBbName(NaClBcIndexSize_t Index, StringType &Name) final; | 3054 void setBbName(NaClBcIndexSize_t Index, StringType &Name) override; |
| 3051 }; | 3055 }; |
| 3052 | 3056 |
| 3053 void ModuleValuesymtabParser::setValueName(NaClBcIndexSize_t Index, | 3057 void ModuleValuesymtabParser::setValueName(NaClBcIndexSize_t Index, |
| 3054 StringType &Name) { | 3058 StringType &Name) { |
| 3055 Ice::GlobalDeclaration *Decl = Context->getGlobalDeclarationByID(Index); | 3059 Ice::GlobalDeclaration *Decl = Context->getGlobalDeclarationByID(Index); |
| 3056 if (llvm::isa<Ice::VariableDeclaration>(Decl) && | 3060 if (llvm::isa<Ice::VariableDeclaration>(Decl) && |
| 3057 Decl->isPNaClABIExternalName(Name.str())) { | 3061 Decl->isPNaClABIExternalName(Name.str())) { |
| 3058 // Force linkage of (specific) Global Variables be external for the PNaCl | 3062 // Force linkage of (specific) Global Variables be external for the PNaCl |
| 3059 // ABI. PNaCl bitcode has a linkage field for Functions, but not for | 3063 // ABI. PNaCl bitcode has a linkage field for Functions, but not for |
| 3060 // GlobalVariables (because the latter is not needed for pexes, so it has | 3064 // GlobalVariables (because the latter is not needed for pexes, so it has |
| 3061 // been removed). | 3065 // been removed). |
| 3062 Decl->setLinkage(llvm::GlobalValue::ExternalLinkage); | 3066 Decl->setLinkage(llvm::GlobalValue::ExternalLinkage); |
| 3063 } | 3067 } |
| 3064 | 3068 |
| 3065 // Unconditionally capture the name if it is provided in the input file, | 3069 // Unconditionally capture the name if it is provided in the input file, |
| 3066 // regardless of whether dump is enabled or whether the symbol is internal vs | 3070 // regardless of whether dump is enabled or whether the symbol is internal vs |
| 3067 // external. This fits in well with the lit tests, and most symbols in a | 3071 // external. This fits in well with the lit tests, and most symbols in a |
| 3068 // conforming pexe are nameless and don't take this path. | 3072 // conforming pexe are nameless and don't take this path. |
| 3069 Decl->setName(getTranslator().getContext(), | 3073 Decl->setName(getTranslator().getContext(), |
| 3070 StringRef(Name.data(), Name.size())); | 3074 StringRef(Name.data(), Name.size())); |
| 3071 } | 3075 } |
| 3072 | 3076 |
| 3073 void ModuleValuesymtabParser::setBbName(NaClBcIndexSize_t Index, | 3077 void ModuleValuesymtabParser::setBbName(NaClBcIndexSize_t Index, |
| 3074 StringType &Name) { | 3078 StringType &Name) { |
| 3075 reportUnableToAssign("Basic block", Index, Name); | 3079 reportUnableToAssign("Basic block", Index, Name); |
| 3076 } | 3080 } |
| 3077 | 3081 |
| 3082 class CfgParserWorkItem final : public Ice::OptWorkItem { |
| 3083 CfgParserWorkItem() = delete; |
| 3084 CfgParserWorkItem(const CfgParserWorkItem &) = delete; |
| 3085 CfgParserWorkItem &operator=(const CfgParserWorkItem &) = delete; |
| 3086 |
| 3087 public: |
| 3088 CfgParserWorkItem(unsigned BlockID, NaClBcIndexSize_t FcnId, |
| 3089 ModuleParser *ModParser, std::unique_ptr<uint8_t[]> Buffer, |
| 3090 uintptr_t BufferSize, uint64_t StartBit, uint32_t SeqNumber) |
| 3091 : BlockID(BlockID), FcnId(FcnId), ModParser(ModParser), |
| 3092 Buffer(std::move(Buffer)), BufferSize(BufferSize), StartBit(StartBit), |
| 3093 SeqNumber(SeqNumber) {} |
| 3094 std::unique_ptr<Ice::Cfg> getParsedCfg() override; |
| 3095 ~CfgParserWorkItem() override = default; |
| 3096 |
| 3097 private: |
| 3098 const unsigned BlockID; |
| 3099 const NaClBcIndexSize_t FcnId; |
| 3100 // Note: ModParser can't be const because the function parser needs to |
| 3101 // access non-const member functions (of ModuleParser and TopLevelParser). |
| 3102 // TODO(kschimpf): Fix this issue. |
| 3103 ModuleParser *ModParser; |
| 3104 const std::unique_ptr<uint8_t[]> Buffer; |
| 3105 const uintptr_t BufferSize; |
| 3106 const uint64_t StartBit; |
| 3107 const uint32_t SeqNumber; |
| 3108 }; |
| 3109 |
| 3110 std::unique_ptr<Ice::Cfg> CfgParserWorkItem::getParsedCfg() { |
| 3111 NaClBitstreamCursor &OldCursor(ModParser->getCursor()); |
| 3112 llvm::NaClBitstreamReader Reader(Buffer.get(), Buffer.get() + BufferSize, |
| 3113 OldCursor.getBitStreamReader()); |
| 3114 NaClBitstreamCursor NewCursor(Reader); |
| 3115 NewCursor.JumpToBit(NewCursor.getWordBitNo(StartBit)); |
| 3116 FunctionParser Parser(BlockID, ModParser, FcnId, NewCursor); |
| 3117 return Parser.parseFunction(SeqNumber); |
| 3118 } |
| 3119 |
| 3078 bool ModuleParser::ParseBlock(unsigned BlockID) { | 3120 bool ModuleParser::ParseBlock(unsigned BlockID) { |
| 3079 switch (BlockID) { | 3121 switch (BlockID) { |
| 3080 case naclbitc::BLOCKINFO_BLOCK_ID: | 3122 case naclbitc::BLOCKINFO_BLOCK_ID: |
| 3081 return NaClBitcodeParser::ParseBlock(BlockID); | 3123 return NaClBitcodeParser::ParseBlock(BlockID); |
| 3082 case naclbitc::TYPE_BLOCK_ID_NEW: { | 3124 case naclbitc::TYPE_BLOCK_ID_NEW: { |
| 3083 TypesParser Parser(BlockID, this); | 3125 TypesParser Parser(BlockID, this); |
| 3084 return Parser.ParseThisBlock(); | 3126 return Parser.ParseThisBlock(); |
| 3085 } | 3127 } |
| 3086 case naclbitc::GLOBALVAR_BLOCK_ID: { | 3128 case naclbitc::GLOBALVAR_BLOCK_ID: { |
| 3087 GlobalsParser Parser(BlockID, this); | 3129 GlobalsParser Parser(BlockID, this); |
| 3088 return Parser.ParseThisBlock(); | 3130 return Parser.ParseThisBlock(); |
| 3089 } | 3131 } |
| 3090 case naclbitc::VALUE_SYMTAB_BLOCK_ID: { | 3132 case naclbitc::VALUE_SYMTAB_BLOCK_ID: { |
| 3091 if (FoundValuesymtab) | 3133 if (FoundValuesymtab) |
| 3092 Fatal("Duplicate valuesymtab in module"); | 3134 Fatal("Duplicate valuesymtab in module"); |
| 3093 | 3135 |
| 3094 // If we have already processed a function block (i.e. we have already | 3136 // If we have already processed a function block (i.e. we have already |
| 3095 // installed global names and variable initializers) we can no longer accept | 3137 // installed global names and variable initializers) we can no longer accept |
| 3096 // the value symbol table. Names have already been generated. | 3138 // the value symbol table. Names have already been generated. |
| 3097 if (GlobalDeclarationNamesAndInitializersInstalled) | 3139 if (GlobalDeclarationNamesAndInitializersInstalled) |
| 3098 Fatal("Module valuesymtab not allowed after function blocks"); | 3140 Fatal("Module valuesymtab not allowed after function blocks"); |
| 3099 | 3141 |
| 3100 FoundValuesymtab = true; | 3142 FoundValuesymtab = true; |
| 3101 ModuleValuesymtabParser Parser(BlockID, this); | 3143 ModuleValuesymtabParser Parser(BlockID, this); |
| 3102 return Parser.ParseThisBlock(); | 3144 return Parser.ParseThisBlock(); |
| 3103 } | 3145 } |
| 3104 case naclbitc::FUNCTION_BLOCK_ID: { | 3146 case naclbitc::FUNCTION_BLOCK_ID: { |
| 3105 installGlobalNamesAndGlobalVarInitializers(); | 3147 installGlobalNamesAndGlobalVarInitializers(); |
| 3106 FunctionParser Parser(BlockID, this); | 3148 Ice::GlobalContext *Ctx = Context->getTranslator().getContext(); |
| 3107 return Parser.convertFunction(); | 3149 uint32_t SeqNumber = Context->getTranslator().getNextSequenceNumber(); |
| 3150 NaClBcIndexSize_t FcnId = Context->getNextFunctionBlockValueID(); |
| 3151 if (Ctx->getFlags().getParseParallel()) { |
| 3152 // Skip the block and copy into a buffer. Note: We copy into a buffer |
| 3153 // using the top-level parser to make sure that the underlying |
| 3154 // buffer reading from the data streamer is not thread safe. |
| 3155 NaClBitstreamCursor &Cursor = Record.GetCursor(); |
| 3156 uint64_t StartBit = Cursor.GetCurrentBitNo(); |
| 3157 if (SkipBlock()) |
| 3158 return true; |
| 3159 const uint64_t EndBit = Cursor.GetCurrentBitNo(); |
| 3160 const uintptr_t StartByte = Cursor.getStartWordByteForBit(StartBit); |
| 3161 const uintptr_t EndByte = Cursor.getEndWordByteForBit(EndBit); |
| 3162 const uintptr_t BufferSize = EndByte - StartByte; |
| 3163 std::unique_ptr<uint8_t[]> Buffer((uint8_t *)(new uint8_t[BufferSize])); |
| 3164 for (size_t i = Cursor.fillBuffer(Buffer.get(), BufferSize, StartByte); |
| 3165 i < BufferSize; ++i) { |
| 3166 Buffer[i] = 0; |
| 3167 } |
| 3168 Ctx->optQueueBlockingPush(Ice::makeUnique<CfgParserWorkItem>( |
| 3169 BlockID, FcnId, this, std::move(Buffer), BufferSize, StartBit, |
| 3170 SeqNumber)); |
| 3171 return false; |
| 3172 } else { |
| 3173 FunctionParser Parser(BlockID, this, FcnId); |
| 3174 std::unique_ptr<Ice::Cfg> Func = Parser.parseFunction(SeqNumber); |
| 3175 bool Failed = Func->hasError(); |
| 3176 getTranslator().translateFcn(std::move(Func)); |
| 3177 return Failed && !getTranslator().getFlags().getAllowErrorRecovery(); |
| 3178 } |
| 3108 } | 3179 } |
| 3109 default: | 3180 default: |
| 3110 return BlockParserBaseClass::ParseBlock(BlockID); | 3181 return BlockParserBaseClass::ParseBlock(BlockID); |
| 3111 } | 3182 } |
| 3112 } | 3183 } |
| 3113 | 3184 |
| 3114 void ModuleParser::ProcessRecord() { | 3185 void ModuleParser::ProcessRecord() { |
| 3115 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); | 3186 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); |
| 3116 switch (Record.GetCode()) { | 3187 switch (Record.GetCode()) { |
| 3117 case naclbitc::MODULE_CODE_VERSION: { | 3188 case naclbitc::MODULE_CODE_VERSION: { |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3225 raw_string_ostream StrBuf(Buffer); | 3296 raw_string_ostream StrBuf(Buffer); |
| 3226 StrBuf << IRFilename << ": Does not contain a module!"; | 3297 StrBuf << IRFilename << ": Does not contain a module!"; |
| 3227 llvm::report_fatal_error(StrBuf.str()); | 3298 llvm::report_fatal_error(StrBuf.str()); |
| 3228 } | 3299 } |
| 3229 if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) { | 3300 if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) { |
| 3230 llvm::report_fatal_error("Bitcode stream should be a multiple of 4 bytes"); | 3301 llvm::report_fatal_error("Bitcode stream should be a multiple of 4 bytes"); |
| 3231 } | 3302 } |
| 3232 } | 3303 } |
| 3233 | 3304 |
| 3234 } // end of namespace Ice | 3305 } // end of namespace Ice |
| OLD | NEW |