Chromium Code Reviews| 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 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 572 Ice::VariableDeclaration * | 565 Ice::VariableDeclaration * |
| 573 reportGetGlobalVariableByIDError(NaClBcIndexSize_t Index); | 566 reportGetGlobalVariableByIDError(NaClBcIndexSize_t Index); |
| 574 | 567 |
| 575 // Reports that there is no corresponding ICE type for LLVMTy, and returns | 568 // Reports that there is no corresponding ICE type for LLVMTy, and returns |
| 576 // Ice::IceType_void. | 569 // Ice::IceType_void. |
| 577 Ice::Type convertToIceTypeError(Type *LLVMTy); | 570 Ice::Type convertToIceTypeError(Type *LLVMTy); |
| 578 }; | 571 }; |
| 579 | 572 |
| 580 bool TopLevelParser::ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit, | 573 bool TopLevelParser::ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit, |
| 581 const std::string &Message) { | 574 const std::string &Message) { |
| 582 ErrorStatus.assign(Ice::EC_Bitcode); | |
| 583 ++NumErrors; | |
| 584 Ice::GlobalContext *Context = Translator.getContext(); | 575 Ice::GlobalContext *Context = Translator.getContext(); |
| 576 { | |
| 577 std::unique_lock<Ice::GlobalLockType> _(ErrorReportingLock); | |
| 578 ErrorStatus.assign(Ice::EC_Bitcode); | |
| 579 } | |
| 585 { // Lock while printing out error message. | 580 { // Lock while printing out error message. |
| 586 Ice::OstreamLocker L(Context); | 581 Ice::OstreamLocker L(Context); |
| 587 raw_ostream &OldErrStream = setErrStream(Context->getStrError()); | 582 raw_ostream &OldErrStream = setErrStream(Context->getStrError()); |
| 588 NaClBitcodeParser::ErrorAt(Level, Bit, Message); | 583 NaClBitcodeParser::ErrorAt(Level, Bit, Message); |
| 589 setErrStream(OldErrStream); | 584 setErrStream(OldErrStream); |
| 590 } | 585 } |
| 591 if (Level >= naclbitc::Error && | 586 if (Level >= naclbitc::Error && |
| 592 !Translator.getFlags().getAllowErrorRecovery()) | 587 !Translator.getFlags().getAllowErrorRecovery()) |
| 593 Fatal(); | 588 Fatal(); |
| 594 return true; | 589 return true; |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 653 // the base class of block parsers, we generate error messages if ParseBlock or | 648 // the base class of block parsers, we generate error messages if ParseBlock or |
| 654 // ParseRecord is not overridden in derived classes. | 649 // ParseRecord is not overridden in derived classes. |
| 655 class BlockParserBaseClass : public NaClBitcodeParser { | 650 class BlockParserBaseClass : public NaClBitcodeParser { |
| 656 BlockParserBaseClass() = delete; | 651 BlockParserBaseClass() = delete; |
| 657 BlockParserBaseClass(const BlockParserBaseClass &) = delete; | 652 BlockParserBaseClass(const BlockParserBaseClass &) = delete; |
| 658 BlockParserBaseClass &operator=(const BlockParserBaseClass &) = delete; | 653 BlockParserBaseClass &operator=(const BlockParserBaseClass &) = delete; |
| 659 | 654 |
| 660 public: | 655 public: |
| 661 // Constructor for the top-level module block parser. | 656 // Constructor for the top-level module block parser. |
| 662 BlockParserBaseClass(unsigned BlockID, TopLevelParser *Context) | 657 BlockParserBaseClass(unsigned BlockID, TopLevelParser *Context) |
| 663 : NaClBitcodeParser(BlockID, Context), Context(Context) { | 658 : NaClBitcodeParser(BlockID, Context), Context(Context) {} |
| 664 Context->setBlockParser(this); | |
| 665 } | |
| 666 | 659 |
| 667 ~BlockParserBaseClass() override { Context->setBlockParser(nullptr); } | 660 BlockParserBaseClass(unsigned BlockID, BlockParserBaseClass *EnclosingParser, |
| 661 NaClBitstreamCursor &Cursor) | |
| 662 : NaClBitcodeParser(BlockID, EnclosingParser, Cursor), | |
| 663 Context(EnclosingParser->Context) {} | |
| 664 | |
| 665 ~BlockParserBaseClass() override {} | |
| 668 | 666 |
| 669 // Returns the printable name of the type of block being parsed. | 667 // Returns the printable name of the type of block being parsed. |
| 670 virtual const char *getBlockName() const { | 668 virtual const char *getBlockName() const { |
| 671 // If this class is used, it is parsing an unknown block. | 669 // If this class is used, it is parsing an unknown block. |
| 672 return "unknown"; | 670 return "unknown"; |
| 673 } | 671 } |
| 674 | 672 |
| 675 // Generates an error Message with the Bit address prefixed to it. | 673 // Generates an error Message with the Bit address prefixed to it. |
| 676 bool ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit, | 674 bool ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit, |
| 677 const std::string &Message) final; | 675 const std::string &Message) override; |
| 678 | 676 |
| 679 protected: | 677 protected: |
| 680 // The context parser that contains the decoded state. | 678 // The context parser that contains the decoded state. |
| 681 TopLevelParser *Context; | 679 TopLevelParser *Context; |
| 680 // True if ErrorAt has been called in this block. | |
| 681 bool BlockHasError = false; | |
| 682 | 682 |
| 683 // Constructor for nested block parsers. | 683 // Constructor for nested block parsers. |
| 684 BlockParserBaseClass(unsigned BlockID, BlockParserBaseClass *EnclosingParser) | 684 BlockParserBaseClass(unsigned BlockID, BlockParserBaseClass *EnclosingParser) |
| 685 : NaClBitcodeParser(BlockID, EnclosingParser), | 685 : NaClBitcodeParser(BlockID, EnclosingParser), |
| 686 Context(EnclosingParser->Context) {} | 686 Context(EnclosingParser->Context) {} |
| 687 | 687 |
| 688 // Gets the translator associated with the bitcode parser. | 688 // Gets the translator associated with the bitcode parser. |
| 689 Ice::Translator &getTranslator() const { return Context->getTranslator(); } | 689 Ice::Translator &getTranslator() const { return Context->getTranslator(); } |
| 690 | 690 |
| 691 const Ice::ClFlags &getFlags() const { return getTranslator().getFlags(); } | 691 const Ice::ClFlags &getFlags() const { return getTranslator().getFlags(); } |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 740 private: | 740 private: |
| 741 /// Generates a record size error. ExpectedSize is the number of elements | 741 /// Generates a record size error. ExpectedSize is the number of elements |
| 742 /// expected. RecordName is the name of the kind of record that has incorrect | 742 /// expected. RecordName is the name of the kind of record that has incorrect |
| 743 /// size. ContextMessage (if not nullptr) is appended to "record expects" to | 743 /// size. ContextMessage (if not nullptr) is appended to "record expects" to |
| 744 /// describe how ExpectedSize should be interpreted. | 744 /// describe how ExpectedSize should be interpreted. |
| 745 void reportRecordSizeError(size_t ExpectedSize, const char *RecordName, | 745 void reportRecordSizeError(size_t ExpectedSize, const char *RecordName, |
| 746 const char *ContextMessage); | 746 const char *ContextMessage); |
| 747 }; | 747 }; |
| 748 | 748 |
| 749 bool TopLevelParser::blockError(const std::string &Message) { | 749 bool TopLevelParser::blockError(const std::string &Message) { |
| 750 if (BlockParser) | 750 // TODO(kschimpf): Remove this method. This method used to redirect |
| 751 return BlockParser->Error(Message); | 751 // block-level errors to the block we are in, rather than the top-level |
| 752 else | 752 // block. This gave better bit location for error messages. However, with |
| 753 return Error(Message); | 753 // parallel parsing, we can't keep a field to redirect (there could be many |
| 754 // and we don't know which block parser applies). Hence, This redirect can't | |
| 755 // be applied anymore. | |
| 756 return Error(Message); | |
| 754 } | 757 } |
| 755 | 758 |
| 756 // Generates an error Message with the bit address prefixed to it. | 759 // Generates an error Message with the bit address prefixed to it. |
| 757 bool BlockParserBaseClass::ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit, | 760 bool BlockParserBaseClass::ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit, |
| 758 const std::string &Message) { | 761 const std::string &Message) { |
| 762 BlockHasError = true; | |
| 759 std::string Buffer; | 763 std::string Buffer; |
| 760 raw_string_ostream StrBuf(Buffer); | 764 raw_string_ostream StrBuf(Buffer); |
| 761 // Note: If dump routines have been turned off, the error messages will not | 765 // Note: If dump routines have been turned off, the error messages will not |
| 762 // be readable. Hence, replace with simple error. We also use the simple form | 766 // be readable. Hence, replace with simple error. We also use the simple form |
| 763 // for unit tests. | 767 // for unit tests. |
| 764 if (getFlags().getGenerateUnitTestMessages()) { | 768 if (getFlags().getGenerateUnitTestMessages()) { |
| 765 StrBuf << "Invalid " << getBlockName() << " record: <" << Record.GetCode(); | 769 StrBuf << "Invalid " << getBlockName() << " record: <" << Record.GetCode(); |
| 766 for (const uint64_t Val : Record.GetValues()) { | 770 for (const uint64_t Val : Record.GetValues()) { |
| 767 StrBuf << " " << Val; | 771 StrBuf << " " << Val; |
| 768 } | 772 } |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 805 void BlockParserBaseClass::ProcessRecord() { | 809 void BlockParserBaseClass::ProcessRecord() { |
| 806 // If called, derived class doesn't know how to handle. | 810 // If called, derived class doesn't know how to handle. |
| 807 std::string Buffer; | 811 std::string Buffer; |
| 808 raw_string_ostream StrBuf(Buffer); | 812 raw_string_ostream StrBuf(Buffer); |
| 809 StrBuf << "Don't know how to process " << getBlockName() | 813 StrBuf << "Don't know how to process " << getBlockName() |
| 810 << " record:" << Record; | 814 << " record:" << Record; |
| 811 Error(StrBuf.str()); | 815 Error(StrBuf.str()); |
| 812 } | 816 } |
| 813 | 817 |
| 814 // Class to parse a types block. | 818 // Class to parse a types block. |
| 815 class TypesParser : public BlockParserBaseClass { | 819 class TypesParser final : public BlockParserBaseClass { |
| 816 TypesParser() = delete; | 820 TypesParser() = delete; |
| 817 TypesParser(const TypesParser &) = delete; | 821 TypesParser(const TypesParser &) = delete; |
| 818 TypesParser &operator=(const TypesParser &) = delete; | 822 TypesParser &operator=(const TypesParser &) = delete; |
| 819 | 823 |
| 820 public: | 824 public: |
| 821 TypesParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) | 825 TypesParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) |
| 822 : BlockParserBaseClass(BlockID, EnclosingParser), | 826 : BlockParserBaseClass(BlockID, EnclosingParser), |
| 823 Timer(Ice::TimerStack::TT_parseTypes, getTranslator().getContext()) {} | 827 Timer(Ice::TimerStack::TT_parseTypes, getTranslator().getContext()) {} |
| 824 | 828 |
| 825 ~TypesParser() override { | 829 ~TypesParser() override { |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1009 } | 1013 } |
| 1010 default: | 1014 default: |
| 1011 BlockParserBaseClass::ProcessRecord(); | 1015 BlockParserBaseClass::ProcessRecord(); |
| 1012 return; | 1016 return; |
| 1013 } | 1017 } |
| 1014 llvm_unreachable("Unknown type block record not processed!"); | 1018 llvm_unreachable("Unknown type block record not processed!"); |
| 1015 } | 1019 } |
| 1016 | 1020 |
| 1017 /// Parses the globals block (i.e. global variable declarations and | 1021 /// Parses the globals block (i.e. global variable declarations and |
| 1018 /// corresponding initializers). | 1022 /// corresponding initializers). |
| 1019 class GlobalsParser : public BlockParserBaseClass { | 1023 class GlobalsParser final : public BlockParserBaseClass { |
| 1020 GlobalsParser() = delete; | 1024 GlobalsParser() = delete; |
| 1021 GlobalsParser(const GlobalsParser &) = delete; | 1025 GlobalsParser(const GlobalsParser &) = delete; |
| 1022 GlobalsParser &operator=(const GlobalsParser &) = delete; | 1026 GlobalsParser &operator=(const GlobalsParser &) = delete; |
| 1023 | 1027 |
| 1024 public: | 1028 public: |
| 1025 GlobalsParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) | 1029 GlobalsParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) |
| 1026 : BlockParserBaseClass(BlockID, EnclosingParser), | 1030 : BlockParserBaseClass(BlockID, EnclosingParser), |
| 1027 Timer(Ice::TimerStack::TT_parseGlobals, getTranslator().getContext()), | 1031 Timer(Ice::TimerStack::TT_parseGlobals, getTranslator().getContext()), |
| 1028 NumFunctionIDs(Context->getNumFunctionIDs()), | 1032 NumFunctionIDs(Context->getNumFunctionIDs()), |
| 1029 DummyGlobalVar(Ice::VariableDeclaration::create( | 1033 DummyGlobalVar(Ice::VariableDeclaration::create( |
| 1030 Context->getGlobalVariablesPool())), | 1034 Context->getGlobalVariablesPool())), |
| 1031 CurGlobalVar(DummyGlobalVar) { | 1035 CurGlobalVar(DummyGlobalVar) { |
| 1032 Context->getGlobalVariablesPool()->willNotBeEmitted(DummyGlobalVar); | 1036 Context->getGlobalVariablesPool()->willNotBeEmitted(DummyGlobalVar); |
| 1033 } | 1037 } |
| 1034 | 1038 |
| 1035 ~GlobalsParser() final = default; | 1039 ~GlobalsParser() override = default; |
| 1036 | 1040 |
| 1037 const char *getBlockName() const override { return "globals"; } | 1041 const char *getBlockName() const override { return "globals"; } |
| 1038 | 1042 |
| 1039 private: | 1043 private: |
| 1040 using GlobalVarsMapType = | 1044 using GlobalVarsMapType = |
| 1041 std::unordered_map<NaClBcIndexSize_t, Ice::VariableDeclaration *>; | 1045 std::unordered_map<NaClBcIndexSize_t, Ice::VariableDeclaration *>; |
| 1042 | 1046 |
| 1043 Ice::TimerMarker Timer; | 1047 Ice::TimerMarker Timer; |
| 1044 | 1048 |
| 1045 // Holds global variables generated/referenced in the global variables block. | 1049 // Holds global variables generated/referenced in the global variables block. |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1329 } | 1333 } |
| 1330 default: | 1334 default: |
| 1331 break; | 1335 break; |
| 1332 } | 1336 } |
| 1333 // If reached, don't know how to handle record. | 1337 // If reached, don't know how to handle record. |
| 1334 BlockParserBaseClass::ProcessRecord(); | 1338 BlockParserBaseClass::ProcessRecord(); |
| 1335 return; | 1339 return; |
| 1336 } | 1340 } |
| 1337 | 1341 |
| 1338 /// Parses function blocks in the bitcode file. | 1342 /// Parses function blocks in the bitcode file. |
| 1339 class FunctionParser : public BlockParserBaseClass { | 1343 class FunctionParser final : public BlockParserBaseClass { |
| 1340 FunctionParser() = delete; | 1344 FunctionParser() = delete; |
| 1341 FunctionParser(const FunctionParser &) = delete; | 1345 FunctionParser(const FunctionParser &) = delete; |
| 1342 FunctionParser &operator=(const FunctionParser &) = delete; | 1346 FunctionParser &operator=(const FunctionParser &) = delete; |
| 1343 | 1347 |
| 1344 public: | 1348 public: |
| 1345 FunctionParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) | 1349 FunctionParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser, |
| 1350 NaClBcIndexSize_t FcnId) | |
| 1346 : BlockParserBaseClass(BlockID, EnclosingParser), | 1351 : BlockParserBaseClass(BlockID, EnclosingParser), |
| 1347 Timer(Ice::TimerStack::TT_parseFunctions, getTranslator().getContext()), | 1352 Timer(Ice::TimerStack::TT_parseFunctions, getTranslator().getContext()), |
| 1348 Func(nullptr), FcnId(Context->getNextFunctionBlockValueID()), | 1353 Func(nullptr), FuncDecl(Context->getFunctionByID(FcnId)), |
| 1349 FuncDecl(Context->getFunctionByID(FcnId)), | |
| 1350 CachedNumGlobalValueIDs(Context->getNumGlobalIDs()), | 1354 CachedNumGlobalValueIDs(Context->getNumGlobalIDs()), |
| 1351 NextLocalInstIndex(Context->getNumGlobalIDs()) {} | 1355 NextLocalInstIndex(Context->getNumGlobalIDs()) {} |
| 1352 | 1356 |
| 1353 bool convertFunction() { | 1357 FunctionParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser, |
| 1358 NaClBcIndexSize_t FcnId, NaClBitstreamCursor &Cursor) | |
| 1359 : BlockParserBaseClass(BlockID, EnclosingParser, Cursor), | |
| 1360 Timer(Ice::TimerStack::TT_parseFunctions, getTranslator().getContext()), | |
| 1361 Func(nullptr), FuncDecl(Context->getFunctionByID(FcnId)), | |
| 1362 CachedNumGlobalValueIDs(Context->getNumGlobalIDs()), | |
| 1363 NextLocalInstIndex(Context->getNumGlobalIDs()) {} | |
| 1364 | |
| 1365 std::unique_ptr<Ice::Cfg> parseFunction(uint32_t SeqNumber) { | |
| 1354 bool ParserResult; | 1366 bool ParserResult; |
| 1367 Ice::GlobalContext *Ctx = getTranslator().getContext(); | |
| 1355 { | 1368 { |
| 1356 Ice::TimerMarker T(getTranslator().getContext(), FuncDecl->getName()); | 1369 Ice::TimerMarker T(Ctx, FuncDecl->getName()); |
| 1357 // Note: The Cfg is created, even when IR generation is disabled. This is | 1370 // Note: The Cfg is created, even when IR generation is disabled. This is |
| 1358 // done to install a CfgLocalAllocator for various internal containers. | 1371 // done to install a CfgLocalAllocator for various internal containers. |
| 1359 Func = Ice::Cfg::create(getTranslator().getContext(), | 1372 Func = Ice::Cfg::create(Ctx, SeqNumber); |
| 1360 getTranslator().getNextSequenceNumber()); | |
| 1361 | 1373 |
| 1362 Ice::CfgLocalAllocatorScope _(Func.get()); | 1374 Ice::CfgLocalAllocatorScope _(Func.get()); |
| 1363 | 1375 |
| 1364 // TODO(kschimpf) Clean up API to add a function signature to a CFG. | 1376 // TODO(kschimpf) Clean up API to add a function signature to a CFG. |
| 1365 const Ice::FuncSigType &Signature = FuncDecl->getSignature(); | 1377 const Ice::FuncSigType &Signature = FuncDecl->getSignature(); |
| 1366 | 1378 |
| 1367 Func->setFunctionName(FuncDecl->getName()); | 1379 Func->setFunctionName(FuncDecl->getName()); |
| 1368 Func->setReturnType(Signature.getReturnType()); | 1380 Func->setReturnType(Signature.getReturnType()); |
| 1369 Func->setInternal(FuncDecl->getLinkage() == GlobalValue::InternalLinkage); | 1381 Func->setInternal(FuncDecl->getLinkage() == GlobalValue::InternalLinkage); |
| 1370 CurrentNode = installNextBasicBlock(); | 1382 CurrentNode = installNextBasicBlock(); |
| 1371 Func->setEntryNode(CurrentNode); | 1383 Func->setEntryNode(CurrentNode); |
| 1372 for (Ice::Type ArgType : Signature.getArgList()) { | 1384 for (Ice::Type ArgType : Signature.getArgList()) { |
| 1373 Func->addArg(getNextInstVar(ArgType)); | 1385 Func->addArg(getNextInstVar(ArgType)); |
| 1374 } | 1386 } |
| 1375 | 1387 |
| 1376 ParserResult = ParseThisBlock(); | 1388 ParserResult = ParseThisBlock(); |
| 1377 | |
| 1378 // Note: Once any errors have been found, we turn off all translation of | |
| 1379 // all remaining functions. This allows successive parsing errors to be | |
| 1380 // reported, without adding extra checks to the translator for such | |
| 1381 // parsing errors. | |
| 1382 } | |
| 1383 if (Context->getNumErrors() == 0 && Func) { | |
| 1384 getTranslator().translateFcn(std::move(Func)); | |
| 1385 // The translator now has ownership of Func. | |
| 1386 } else { | |
| 1387 Func.reset(); | |
| 1388 } | 1389 } |
| 1389 | 1390 |
| 1390 return ParserResult; | 1391 if (ParserResult || BlockHasError) |
| 1392 Func->setError("Unable to parse function"); | |
| 1393 | |
| 1394 return std::move(Func); | |
| 1391 } | 1395 } |
| 1392 | 1396 |
| 1393 ~FunctionParser() final = default; | 1397 ~FunctionParser() override = default; |
| 1394 | 1398 |
| 1395 const char *getBlockName() const override { return "function"; } | 1399 const char *getBlockName() const override { return "function"; } |
| 1396 | 1400 |
| 1397 Ice::Cfg *getFunc() const { return Func.get(); } | 1401 Ice::Cfg *getFunc() const { return Func.get(); } |
| 1398 | 1402 |
| 1399 size_t getNumGlobalIDs() const { return CachedNumGlobalValueIDs; } | 1403 size_t getNumGlobalIDs() const { return CachedNumGlobalValueIDs; } |
| 1400 | 1404 |
| 1401 void setNextLocalInstIndex(Ice::Operand *Op) { | 1405 void setNextLocalInstIndex(Ice::Operand *Op) { |
| 1402 setOperand(NextLocalInstIndex++, Op); | 1406 setOperand(NextLocalInstIndex++, Op); |
| 1403 } | 1407 } |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 1427 // the number of bytes defining the function block. | 1431 // the number of bytes defining the function block. |
| 1428 uint64_t MaxRecordsInBlock = 0; | 1432 uint64_t MaxRecordsInBlock = 0; |
| 1429 // The corresponding ICE function defined by the function block. | 1433 // The corresponding ICE function defined by the function block. |
| 1430 std::unique_ptr<Ice::Cfg> Func; | 1434 std::unique_ptr<Ice::Cfg> Func; |
| 1431 // The index to the current basic block being built. | 1435 // The index to the current basic block being built. |
| 1432 NaClBcIndexSize_t CurrentBbIndex = 0; | 1436 NaClBcIndexSize_t CurrentBbIndex = 0; |
| 1433 // The number of basic blocks declared for the function block. | 1437 // The number of basic blocks declared for the function block. |
| 1434 NaClBcIndexSize_t DeclaredNumberBbs = 0; | 1438 NaClBcIndexSize_t DeclaredNumberBbs = 0; |
| 1435 // The basic block being built. | 1439 // The basic block being built. |
| 1436 Ice::CfgNode *CurrentNode = nullptr; | 1440 Ice::CfgNode *CurrentNode = nullptr; |
| 1437 // The ID for the function. | |
| 1438 NaClBcIndexSize_t FcnId; | |
| 1439 // The corresponding function declaration. | 1441 // The corresponding function declaration. |
| 1440 Ice::FunctionDeclaration *FuncDecl; | 1442 Ice::FunctionDeclaration *FuncDecl; |
| 1441 // Holds the dividing point between local and global absolute value indices. | 1443 // Holds the dividing point between local and global absolute value indices. |
| 1442 size_t CachedNumGlobalValueIDs; | 1444 size_t CachedNumGlobalValueIDs; |
| 1443 // Holds operands local to the function block, based on indices defined in | 1445 // Holds operands local to the function block, based on indices defined in |
| 1444 // the bitcode file. | 1446 // the bitcode file. |
| 1445 Ice::OperandList LocalOperands; | 1447 Ice::OperandList LocalOperands; |
| 1446 // Holds the index within LocalOperands corresponding to the next instruction | 1448 // Holds the index within LocalOperands corresponding to the next instruction |
| 1447 // that generates a value. | 1449 // that generates a value. |
| 1448 NaClBcIndexSize_t NextLocalInstIndex; | 1450 NaClBcIndexSize_t NextLocalInstIndex; |
| 1449 // True if the last processed instruction was a terminating instruction. | 1451 // True if the last processed instruction was a terminating instruction. |
| 1450 bool InstIsTerminating = false; | 1452 bool InstIsTerminating = false; |
| 1451 | 1453 |
| 1452 bool ParseBlock(unsigned BlockID) override; | 1454 bool ParseBlock(unsigned BlockID) override; |
| 1453 | 1455 |
| 1454 void ProcessRecord() override; | 1456 void ProcessRecord() override; |
| 1455 | 1457 |
| 1456 void EnterBlock(unsigned NumWords) final { | 1458 void EnterBlock(unsigned NumWords) override { |
| 1457 // Note: Bitstream defines words as 32-bit values. | 1459 // Note: Bitstream defines words as 32-bit values. |
| 1458 NumBytesDefiningFunction = NumWords * sizeof(uint32_t); | 1460 NumBytesDefiningFunction = NumWords * sizeof(uint32_t); |
| 1459 // We know that all records are minimally defined by a two-bit abreviation. | 1461 // We know that all records are minimally defined by a two-bit abreviation. |
| 1460 MaxRecordsInBlock = NumBytesDefiningFunction * (CHAR_BIT >> 1); | 1462 MaxRecordsInBlock = NumBytesDefiningFunction * (CHAR_BIT >> 1); |
| 1461 } | 1463 } |
| 1462 | 1464 |
| 1463 void ExitBlock() override; | 1465 void ExitBlock() override; |
| 1464 | 1466 |
| 1465 // Creates and appends a new basic block to the list of basic blocks. | 1467 // Creates and appends a new basic block to the list of basic blocks. |
| 1466 Ice::CfgNode *installNextBasicBlock() { | 1468 Ice::CfgNode *installNextBasicBlock() { |
| (...skipping 1300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2767 return; | 2769 return; |
| 2768 } | 2770 } |
| 2769 default: | 2771 default: |
| 2770 // Generate error message! | 2772 // Generate error message! |
| 2771 BlockParserBaseClass::ProcessRecord(); | 2773 BlockParserBaseClass::ProcessRecord(); |
| 2772 return; | 2774 return; |
| 2773 } | 2775 } |
| 2774 } | 2776 } |
| 2775 | 2777 |
| 2776 /// Parses constants within a function block. | 2778 /// Parses constants within a function block. |
| 2777 class ConstantsParser : public BlockParserBaseClass { | 2779 class ConstantsParser final : public BlockParserBaseClass { |
| 2778 ConstantsParser() = delete; | 2780 ConstantsParser() = delete; |
| 2779 ConstantsParser(const ConstantsParser &) = delete; | 2781 ConstantsParser(const ConstantsParser &) = delete; |
| 2780 ConstantsParser &operator=(const ConstantsParser &) = delete; | 2782 ConstantsParser &operator=(const ConstantsParser &) = delete; |
| 2781 | 2783 |
| 2782 public: | 2784 public: |
| 2783 ConstantsParser(unsigned BlockID, FunctionParser *FuncParser) | 2785 ConstantsParser(unsigned BlockID, FunctionParser *FuncParser) |
| 2784 : BlockParserBaseClass(BlockID, FuncParser), | 2786 : BlockParserBaseClass(BlockID, FuncParser), |
| 2785 Timer(Ice::TimerStack::TT_parseConstants, getTranslator().getContext()), | 2787 Timer(Ice::TimerStack::TT_parseConstants, getTranslator().getContext()), |
| 2786 FuncParser(FuncParser) {} | 2788 FuncParser(FuncParser) {} |
| 2787 | 2789 |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2884 } | 2886 } |
| 2885 } | 2887 } |
| 2886 default: | 2888 default: |
| 2887 // Generate error message! | 2889 // Generate error message! |
| 2888 BlockParserBaseClass::ProcessRecord(); | 2890 BlockParserBaseClass::ProcessRecord(); |
| 2889 return; | 2891 return; |
| 2890 } | 2892 } |
| 2891 } | 2893 } |
| 2892 | 2894 |
| 2893 // Parses valuesymtab blocks appearing in a function block. | 2895 // Parses valuesymtab blocks appearing in a function block. |
| 2894 class FunctionValuesymtabParser : public ValuesymtabParser { | 2896 class FunctionValuesymtabParser final : public ValuesymtabParser { |
| 2895 FunctionValuesymtabParser() = delete; | 2897 FunctionValuesymtabParser() = delete; |
| 2896 FunctionValuesymtabParser(const FunctionValuesymtabParser &) = delete; | 2898 FunctionValuesymtabParser(const FunctionValuesymtabParser &) = delete; |
| 2897 void operator=(const FunctionValuesymtabParser &) = delete; | 2899 void operator=(const FunctionValuesymtabParser &) = delete; |
| 2898 | 2900 |
| 2899 public: | 2901 public: |
| 2900 FunctionValuesymtabParser(unsigned BlockID, FunctionParser *EnclosingParser) | 2902 FunctionValuesymtabParser(unsigned BlockID, FunctionParser *EnclosingParser) |
| 2901 : ValuesymtabParser(BlockID, EnclosingParser), | 2903 : ValuesymtabParser(BlockID, EnclosingParser), |
| 2902 Timer(Ice::TimerStack::TT_parseFunctionValuesymtabs, | 2904 Timer(Ice::TimerStack::TT_parseFunctionValuesymtabs, |
| 2903 getTranslator().getContext()) {} | 2905 getTranslator().getContext()) {} |
| 2904 | 2906 |
| 2905 private: | 2907 private: |
| 2906 Ice::TimerMarker Timer; | 2908 Ice::TimerMarker Timer; |
| 2907 // Returns the enclosing function parser. | 2909 // Returns the enclosing function parser. |
| 2908 FunctionParser *getFunctionParser() const { | 2910 FunctionParser *getFunctionParser() const { |
| 2909 return reinterpret_cast<FunctionParser *>(GetEnclosingParser()); | 2911 return reinterpret_cast<FunctionParser *>(GetEnclosingParser()); |
| 2910 } | 2912 } |
| 2911 | 2913 |
| 2912 const char *getTableKind() const final { return "Function"; } | 2914 const char *getTableKind() const override { return "Function"; } |
| 2913 | 2915 |
| 2914 void setValueName(NaClBcIndexSize_t Index, StringType &Name) final; | 2916 void setValueName(NaClBcIndexSize_t Index, StringType &Name) override; |
| 2915 void setBbName(NaClBcIndexSize_t Index, StringType &Name) final; | 2917 void setBbName(NaClBcIndexSize_t Index, StringType &Name) override; |
| 2916 | 2918 |
| 2917 // Reports that the assignment of Name to the value associated with index is | 2919 // Reports that the assignment of Name to the value associated with index is |
| 2918 // not possible, for the given Context. | 2920 // not possible, for the given Context. |
| 2919 void reportUnableToAssign(const char *Context, NaClBcIndexSize_t Index, | 2921 void reportUnableToAssign(const char *Context, NaClBcIndexSize_t Index, |
| 2920 StringType &Name) { | 2922 StringType &Name) { |
| 2921 std::string Buffer; | 2923 std::string Buffer; |
| 2922 raw_string_ostream StrBuf(Buffer); | 2924 raw_string_ostream StrBuf(Buffer); |
| 2923 StrBuf << "Function-local " << Context << " name '" << Name | 2925 StrBuf << "Function-local " << Context << " name '" << Name |
| 2924 << "' can't be associated with index " << Index; | 2926 << "' can't be associated with index " << Index; |
| 2925 Error(StrBuf.str()); | 2927 Error(StrBuf.str()); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2971 } | 2973 } |
| 2972 break; | 2974 break; |
| 2973 } | 2975 } |
| 2974 default: | 2976 default: |
| 2975 break; | 2977 break; |
| 2976 } | 2978 } |
| 2977 return BlockParserBaseClass::ParseBlock(BlockID); | 2979 return BlockParserBaseClass::ParseBlock(BlockID); |
| 2978 } | 2980 } |
| 2979 | 2981 |
| 2980 /// Parses the module block in the bitcode file. | 2982 /// Parses the module block in the bitcode file. |
| 2981 class ModuleParser : public BlockParserBaseClass { | 2983 class ModuleParser final : public BlockParserBaseClass { |
| 2982 ModuleParser() = delete; | 2984 ModuleParser() = delete; |
| 2983 ModuleParser(const ModuleParser &) = delete; | 2985 ModuleParser(const ModuleParser &) = delete; |
| 2984 ModuleParser &operator=(const ModuleParser &) = delete; | 2986 ModuleParser &operator=(const ModuleParser &) = delete; |
| 2985 | 2987 |
| 2986 public: | 2988 public: |
| 2987 ModuleParser(unsigned BlockID, TopLevelParser *Context) | 2989 ModuleParser(unsigned BlockID, TopLevelParser *Context) |
| 2988 : BlockParserBaseClass(BlockID, Context), | 2990 : BlockParserBaseClass(BlockID, Context), |
| 2989 Timer(Ice::TimerStack::TT_parseModule, | 2991 Timer(Ice::TimerStack::TT_parseModule, |
| 2990 Context->getTranslator().getContext()) {} | 2992 Context->getTranslator().getContext()) {} |
| 2991 | |
| 2992 ~ModuleParser() override = default; | 2993 ~ModuleParser() override = default; |
| 2993 | |
| 2994 const char *getBlockName() const override { return "module"; } | 2994 const char *getBlockName() const override { return "module"; } |
| 2995 NaClBitstreamCursor &getCursor() const { return Record.GetCursor(); } | |
| 2995 | 2996 |
| 2996 private: | 2997 private: |
| 2997 Ice::TimerMarker Timer; | 2998 Ice::TimerMarker Timer; |
| 2998 // True if we have already installed names for unnamed global declarations, | 2999 // True if we have already installed names for unnamed global declarations, |
| 2999 // and have generated global constant initializers. | 3000 // and have generated global constant initializers. |
| 3000 bool GlobalDeclarationNamesAndInitializersInstalled = false; | 3001 bool GlobalDeclarationNamesAndInitializersInstalled = false; |
| 3001 // True if we have already processed the symbol table for the module. | 3002 // True if we have already processed the symbol table for the module. |
| 3002 bool FoundValuesymtab = false; | 3003 bool FoundValuesymtab = false; |
| 3003 | 3004 |
| 3004 // Generates names for unnamed global addresses (i.e. functions and global | 3005 // Generates names for unnamed global addresses (i.e. functions and global |
| 3005 // variables). Then lowers global variable declaration initializers to the | 3006 // variables). Then lowers global variable declaration initializers to the |
| 3006 // target. May be called multiple times. Only the first call will do the | 3007 // target. May be called multiple times. Only the first call will do the |
| 3007 // installation. | 3008 // installation. |
| 3008 void installGlobalNamesAndGlobalVarInitializers() { | 3009 void installGlobalNamesAndGlobalVarInitializers() { |
| 3009 if (!GlobalDeclarationNamesAndInitializersInstalled) { | 3010 if (!GlobalDeclarationNamesAndInitializersInstalled) { |
| 3010 Context->installGlobalNames(); | 3011 Context->installGlobalNames(); |
| 3011 Context->createValueIDs(); | 3012 Context->createValueIDs(); |
| 3012 Context->verifyFunctionTypeSignatures(); | 3013 Context->verifyFunctionTypeSignatures(); |
| 3013 std::unique_ptr<Ice::VariableDeclarationList> Globals = | 3014 std::unique_ptr<Ice::VariableDeclarationList> Globals = |
| 3014 Context->getGlobalVariables(); | 3015 Context->getGlobalVariables(); |
| 3015 if (Globals) | 3016 if (Globals) |
| 3016 getTranslator().lowerGlobals(std::move(Globals)); | 3017 getTranslator().lowerGlobals(std::move(Globals)); |
| 3017 GlobalDeclarationNamesAndInitializersInstalled = true; | 3018 GlobalDeclarationNamesAndInitializersInstalled = true; |
| 3018 } | 3019 } |
| 3019 } | 3020 } |
| 3020 bool ParseBlock(unsigned BlockID) override; | 3021 bool ParseBlock(unsigned BlockID) override; |
| 3021 | 3022 |
| 3022 void ExitBlock() override { installGlobalNamesAndGlobalVarInitializers(); } | 3023 void ExitBlock() override { |
| 3024 installGlobalNamesAndGlobalVarInitializers(); | |
| 3025 Context->getTranslator().getContext()->waitForWorkerThreads(); | |
| 3026 } | |
| 3023 | 3027 |
| 3024 void ProcessRecord() override; | 3028 void ProcessRecord() override; |
| 3025 }; | 3029 }; |
| 3026 | 3030 |
| 3027 class ModuleValuesymtabParser : public ValuesymtabParser { | 3031 class ModuleValuesymtabParser : public ValuesymtabParser { |
| 3028 ModuleValuesymtabParser() = delete; | 3032 ModuleValuesymtabParser() = delete; |
| 3029 ModuleValuesymtabParser(const ModuleValuesymtabParser &) = delete; | 3033 ModuleValuesymtabParser(const ModuleValuesymtabParser &) = delete; |
| 3030 void operator=(const ModuleValuesymtabParser &) = delete; | 3034 void operator=(const ModuleValuesymtabParser &) = delete; |
| 3031 | 3035 |
| 3032 public: | 3036 public: |
| 3033 ModuleValuesymtabParser(unsigned BlockID, ModuleParser *MP) | 3037 ModuleValuesymtabParser(unsigned BlockID, ModuleParser *MP) |
| 3034 : ValuesymtabParser(BlockID, MP), | 3038 : ValuesymtabParser(BlockID, MP), |
| 3035 Timer(Ice::TimerStack::TT_parseModuleValuesymtabs, | 3039 Timer(Ice::TimerStack::TT_parseModuleValuesymtabs, |
| 3036 getTranslator().getContext()) {} | 3040 getTranslator().getContext()) {} |
| 3037 | 3041 |
| 3038 ~ModuleValuesymtabParser() override = default; | 3042 ~ModuleValuesymtabParser() override = default; |
| 3039 | 3043 |
| 3040 private: | 3044 private: |
| 3041 Ice::TimerMarker Timer; | 3045 Ice::TimerMarker Timer; |
| 3042 const char *getTableKind() const final { return "Module"; } | 3046 const char *getTableKind() const override { return "Module"; } |
| 3043 void setValueName(NaClBcIndexSize_t Index, StringType &Name) final; | 3047 void setValueName(NaClBcIndexSize_t Index, StringType &Name) override; |
| 3044 void setBbName(NaClBcIndexSize_t Index, StringType &Name) final; | 3048 void setBbName(NaClBcIndexSize_t Index, StringType &Name) override; |
| 3045 }; | 3049 }; |
| 3046 | 3050 |
| 3047 void ModuleValuesymtabParser::setValueName(NaClBcIndexSize_t Index, | 3051 void ModuleValuesymtabParser::setValueName(NaClBcIndexSize_t Index, |
| 3048 StringType &Name) { | 3052 StringType &Name) { |
| 3049 Ice::GlobalDeclaration *Decl = Context->getGlobalDeclarationByID(Index); | 3053 Ice::GlobalDeclaration *Decl = Context->getGlobalDeclarationByID(Index); |
| 3050 if (llvm::isa<Ice::VariableDeclaration>(Decl) && | 3054 if (llvm::isa<Ice::VariableDeclaration>(Decl) && |
| 3051 Decl->isPNaClABIExternalName(Name.str())) { | 3055 Decl->isPNaClABIExternalName(Name.str())) { |
| 3052 // Force linkage of (specific) Global Variables be external for the PNaCl | 3056 // Force linkage of (specific) Global Variables be external for the PNaCl |
| 3053 // ABI. PNaCl bitcode has a linkage field for Functions, but not for | 3057 // ABI. PNaCl bitcode has a linkage field for Functions, but not for |
| 3054 // GlobalVariables (because the latter is not needed for pexes, so it has | 3058 // GlobalVariables (because the latter is not needed for pexes, so it has |
| 3055 // been removed). | 3059 // been removed). |
| 3056 Decl->setLinkage(llvm::GlobalValue::ExternalLinkage); | 3060 Decl->setLinkage(llvm::GlobalValue::ExternalLinkage); |
| 3057 } | 3061 } |
| 3058 | 3062 |
| 3059 Decl->setName(StringRef(Name.data(), Name.size())); | 3063 Decl->setName(StringRef(Name.data(), Name.size())); |
| 3060 } | 3064 } |
| 3061 | 3065 |
| 3062 void ModuleValuesymtabParser::setBbName(NaClBcIndexSize_t Index, | 3066 void ModuleValuesymtabParser::setBbName(NaClBcIndexSize_t Index, |
| 3063 StringType &Name) { | 3067 StringType &Name) { |
| 3064 reportUnableToAssign("Basic block", Index, Name); | 3068 reportUnableToAssign("Basic block", Index, Name); |
| 3065 } | 3069 } |
| 3066 | 3070 |
| 3071 class CfgParserWorkItem final : public Ice::OptWorkItem { | |
| 3072 CfgParserWorkItem() = delete; | |
| 3073 CfgParserWorkItem(const CfgParserWorkItem &) = delete; | |
| 3074 CfgParserWorkItem &operator=(const CfgParserWorkItem &) = delete; | |
| 3075 | |
| 3076 public: | |
| 3077 CfgParserWorkItem(unsigned BlockID, NaClBcIndexSize_t FcnId, | |
| 3078 ModuleParser *ModParser, std::unique_ptr<uint8_t[]> Buffer, | |
| 3079 uintptr_t BufferSize, uint64_t StartBit, uint32_t SeqNumber) | |
| 3080 : BlockID(BlockID), FcnId(FcnId), ModParser(ModParser), | |
| 3081 Buffer(std::move(Buffer)), BufferSize(BufferSize), StartBit(StartBit), | |
| 3082 SeqNumber(SeqNumber) {} | |
| 3083 std::unique_ptr<Ice::Cfg> getParsedCfg() override; | |
| 3084 ~CfgParserWorkItem() override = default; | |
| 3085 | |
| 3086 private: | |
| 3087 const unsigned BlockID; | |
| 3088 const NaClBcIndexSize_t FcnId; | |
| 3089 const ModuleParser *ModParser; | |
| 3090 std::unique_ptr<uint8_t[]> Buffer; | |
| 3091 uintptr_t BufferSize; | |
| 3092 const uint64_t StartBit; | |
| 3093 const uint32_t SeqNumber; | |
| 3094 }; | |
| 3095 | |
| 3096 std::unique_ptr<Ice::Cfg> CfgParserWorkItem::getParsedCfg() { | |
| 3097 NaClBitstreamCursor &OldCursor(ModParser->getCursor()); | |
| 3098 llvm::NaClBitstreamReader Reader(Buffer.get(), Buffer.get() + BufferSize, | |
| 3099 OldCursor.getBitStreamReader()); | |
| 3100 NaClBitstreamCursor NewCursor(Reader); | |
| 3101 NewCursor.JumpToBit(NewCursor.getWordBitNo(StartBit)); | |
| 3102 FunctionParser Parser(BlockID, const_cast<ModuleParser *>(ModParser), FcnId, | |
|
Jim Stichnoth
2016/03/31 16:08:09
Do you really need that const_cast here? Couldn't
Karl
2016/03/31 16:33:49
I added this (and the necessary const_cast) at Joh
| |
| 3103 NewCursor); | |
| 3104 return Parser.parseFunction(SeqNumber); | |
| 3105 } | |
| 3106 | |
| 3067 bool ModuleParser::ParseBlock(unsigned BlockID) { | 3107 bool ModuleParser::ParseBlock(unsigned BlockID) { |
| 3068 switch (BlockID) { | 3108 switch (BlockID) { |
| 3069 case naclbitc::BLOCKINFO_BLOCK_ID: | 3109 case naclbitc::BLOCKINFO_BLOCK_ID: |
| 3070 return NaClBitcodeParser::ParseBlock(BlockID); | 3110 return NaClBitcodeParser::ParseBlock(BlockID); |
| 3071 case naclbitc::TYPE_BLOCK_ID_NEW: { | 3111 case naclbitc::TYPE_BLOCK_ID_NEW: { |
| 3072 TypesParser Parser(BlockID, this); | 3112 TypesParser Parser(BlockID, this); |
| 3073 return Parser.ParseThisBlock(); | 3113 return Parser.ParseThisBlock(); |
| 3074 } | 3114 } |
| 3075 case naclbitc::GLOBALVAR_BLOCK_ID: { | 3115 case naclbitc::GLOBALVAR_BLOCK_ID: { |
| 3076 GlobalsParser Parser(BlockID, this); | 3116 GlobalsParser Parser(BlockID, this); |
| 3077 return Parser.ParseThisBlock(); | 3117 return Parser.ParseThisBlock(); |
| 3078 } | 3118 } |
| 3079 case naclbitc::VALUE_SYMTAB_BLOCK_ID: { | 3119 case naclbitc::VALUE_SYMTAB_BLOCK_ID: { |
| 3080 if (FoundValuesymtab) | 3120 if (FoundValuesymtab) |
| 3081 Fatal("Duplicate valuesymtab in module"); | 3121 Fatal("Duplicate valuesymtab in module"); |
| 3082 | 3122 |
| 3083 // If we have already processed a function block (i.e. we have already | 3123 // If we have already processed a function block (i.e. we have already |
| 3084 // installed global names and variable initializers) we can no longer accept | 3124 // installed global names and variable initializers) we can no longer accept |
| 3085 // the value symbol table. Names have already been generated. | 3125 // the value symbol table. Names have already been generated. |
| 3086 if (GlobalDeclarationNamesAndInitializersInstalled) | 3126 if (GlobalDeclarationNamesAndInitializersInstalled) |
| 3087 Fatal("Module valuesymtab not allowed after function blocks"); | 3127 Fatal("Module valuesymtab not allowed after function blocks"); |
| 3088 | 3128 |
| 3089 FoundValuesymtab = true; | 3129 FoundValuesymtab = true; |
| 3090 ModuleValuesymtabParser Parser(BlockID, this); | 3130 ModuleValuesymtabParser Parser(BlockID, this); |
| 3091 return Parser.ParseThisBlock(); | 3131 return Parser.ParseThisBlock(); |
| 3092 } | 3132 } |
| 3093 case naclbitc::FUNCTION_BLOCK_ID: { | 3133 case naclbitc::FUNCTION_BLOCK_ID: { |
| 3094 installGlobalNamesAndGlobalVarInitializers(); | 3134 installGlobalNamesAndGlobalVarInitializers(); |
| 3095 FunctionParser Parser(BlockID, this); | 3135 Ice::GlobalContext *Ctx = Context->getTranslator().getContext(); |
| 3096 return Parser.convertFunction(); | 3136 uint32_t SeqNumber = Context->getTranslator().getNextSequenceNumber(); |
| 3137 NaClBcIndexSize_t FcnId = Context->getNextFunctionBlockValueID(); | |
| 3138 if (Ctx->getFlags().getParseParallel()) { | |
| 3139 // Skip the block and copy into a buffer. Note: We copy into a buffer | |
| 3140 // using the top-level parser to make sure that the underlying | |
| 3141 // buffer reading from the data streamer is not thread safe. | |
| 3142 NaClBitstreamCursor &Cursor = Record.GetCursor(); | |
| 3143 uint64_t StartBit = Cursor.GetCurrentBitNo(); | |
| 3144 if (SkipBlock()) | |
| 3145 return true; | |
| 3146 uint64_t EndBit = Cursor.GetCurrentBitNo(); | |
|
John
2016/03/31 15:51:36
can this be const?
Karl
2016/03/31 16:33:49
Done.
| |
| 3147 const uintptr_t StartByte = Cursor.getStartWordByteForBit(StartBit); | |
| 3148 const uintptr_t EndByte = Cursor.getEndWordByteForBit(EndBit); | |
| 3149 const uintptr_t BufferSize = EndByte - StartByte; | |
| 3150 std::unique_ptr<uint8_t[]> Buffer((uint8_t *)(new uint8_t[BufferSize])); | |
| 3151 for (size_t i = Cursor.fillBuffer(Buffer.get(), BufferSize, StartByte); | |
| 3152 i < BufferSize; ++i) { | |
| 3153 Buffer[i] = 0; | |
| 3154 } | |
| 3155 Ctx->optQueueBlockingPush(Ice::makeUnique<CfgParserWorkItem>( | |
| 3156 BlockID, FcnId, this, std::move(Buffer), BufferSize, StartBit, | |
| 3157 SeqNumber)); | |
| 3158 return false; | |
| 3159 } else { | |
| 3160 FunctionParser Parser(BlockID, this, FcnId); | |
| 3161 std::unique_ptr<Ice::Cfg> Func = Parser.parseFunction(SeqNumber); | |
| 3162 bool Failed = Func->hasError(); | |
| 3163 getTranslator().translateFcn(std::move(Func)); | |
| 3164 return Failed && !getTranslator().getFlags().getAllowErrorRecovery(); | |
| 3165 } | |
| 3097 } | 3166 } |
| 3098 default: | 3167 default: |
| 3099 return BlockParserBaseClass::ParseBlock(BlockID); | 3168 return BlockParserBaseClass::ParseBlock(BlockID); |
| 3100 } | 3169 } |
| 3101 } | 3170 } |
| 3102 | 3171 |
| 3103 void ModuleParser::ProcessRecord() { | 3172 void ModuleParser::ProcessRecord() { |
| 3104 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); | 3173 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); |
| 3105 switch (Record.GetCode()) { | 3174 switch (Record.GetCode()) { |
| 3106 case naclbitc::MODULE_CODE_VERSION: { | 3175 case naclbitc::MODULE_CODE_VERSION: { |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3214 raw_string_ostream StrBuf(Buffer); | 3283 raw_string_ostream StrBuf(Buffer); |
| 3215 StrBuf << IRFilename << ": Does not contain a module!"; | 3284 StrBuf << IRFilename << ": Does not contain a module!"; |
| 3216 llvm::report_fatal_error(StrBuf.str()); | 3285 llvm::report_fatal_error(StrBuf.str()); |
| 3217 } | 3286 } |
| 3218 if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) { | 3287 if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) { |
| 3219 llvm::report_fatal_error("Bitcode stream should be a multiple of 4 bytes"); | 3288 llvm::report_fatal_error("Bitcode stream should be a multiple of 4 bytes"); |
| 3220 } | 3289 } |
| 3221 } | 3290 } |
| 3222 | 3291 |
| 3223 } // end of namespace Ice | 3292 } // end of namespace Ice |
| OLD | NEW |