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) { | 240 void setBlockParser(BlockParserBaseClass *NewBlockParser) { |
| 241 BlockParser = NewBlockParser; | 241 BlockParser = NewBlockParser; |
| 242 } | 242 } |
| 243 | 243 |
| 244 /// Generates error with given Message, occurring at BitPosition within the | 244 /// Generates error with given Message, occurring at BitPosition within the |
| 245 /// bitcode file. Always returns true. | 245 /// bitcode file. Always returns true. |
| 246 bool ErrorAt(naclbitc::ErrorLevel Level, uint64_t BitPosition, | 246 bool ErrorAt(naclbitc::ErrorLevel Level, uint64_t BitPosition, |
| 247 const std::string &Message) final; | 247 const std::string &Message) override; |
| 248 | 248 |
| 249 /// Generates error message with respect to the current block parser. | 249 /// Generates error message with respect to the current block parser. |
| 250 bool blockError(const std::string &Message); | 250 bool blockError(const std::string &Message); |
| 251 | 251 |
| 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. | 252 /// Changes the size of the type list to the given size. |
| 256 void resizeTypeIDValues(size_t NewSize) { TypeIDValues.resize(NewSize); } | 253 void resizeTypeIDValues(size_t NewSize) { TypeIDValues.resize(NewSize); } |
| 257 | 254 |
| 258 size_t getNumTypeIDValues() const { return TypeIDValues.size(); } | 255 size_t getNumTypeIDValues() const { return TypeIDValues.size(); } |
| 259 | 256 |
| 260 /// Returns a pointer to the pool where globals are allocated. | 257 /// Returns a pointer to the pool where globals are allocated. |
| 261 Ice::VariableDeclarationList *getGlobalVariablesPool() { | 258 Ice::VariableDeclarationList *getGlobalVariablesPool() { |
| 262 return VariableDeclarations.get(); | 259 return VariableDeclarations.get(); |
| 263 } | 260 } |
| 264 | 261 |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 421 StrBuf << Prefix << " alignment greater than 2**" << AlignPowerLimit | 418 StrBuf << Prefix << " alignment greater than 2**" << AlignPowerLimit |
| 422 << ". Found: 2**" << (AlignPower - 1); | 419 << ". Found: 2**" << (AlignPower - 1); |
| 423 Parser->Error(StrBuf.str()); | 420 Parser->Error(StrBuf.str()); |
| 424 // Error recover with value that is always acceptable. | 421 // Error recover with value that is always acceptable. |
| 425 return 1; | 422 return 1; |
| 426 } | 423 } |
| 427 | 424 |
| 428 private: | 425 private: |
| 429 // The translator associated with the parser. | 426 // The translator associated with the parser. |
| 430 Ice::Translator &Translator; | 427 Ice::Translator &Translator; |
| 428 | |
| 429 // ErrorStatus should only be updated while this lock is locked. | |
| 430 Ice::GlobalLockType ErrorReportingLock; | |
| 431 // The exit status that should be set to true if an error occurs. | 431 // The exit status that should be set to true if an error occurs. |
| 432 Ice::ErrorCode &ErrorStatus; | 432 Ice::ErrorCode &ErrorStatus; |
| 433 // The number of errors reported. | 433 |
| 434 unsigned NumErrors = 0; | |
| 435 // The types associated with each type ID. | 434 // The types associated with each type ID. |
| 436 std::vector<ExtendedType> TypeIDValues; | 435 std::vector<ExtendedType> TypeIDValues; |
| 437 // The set of functions (prototype and defined). | 436 // The set of functions (prototype and defined). |
| 438 Ice::FunctionDeclarationList FunctionDeclarations; | 437 Ice::FunctionDeclarationList FunctionDeclarations; |
| 439 // The ID of the next possible defined function ID in FunctionDeclarations. | 438 // The ID of the next possible defined function ID in FunctionDeclarations. |
| 440 // FunctionDeclarations is filled first. It's the set of functions (either | 439 // FunctionDeclarations is filled first. It's the set of functions (either |
| 441 // defined or isproto). Then function definitions are encountered/parsed and | 440 // defined or isproto). Then function definitions are encountered/parsed and |
| 442 // NextDefiningFunctionID is incremented to track the next actually-defined | 441 // NextDefiningFunctionID is incremented to track the next actually-defined |
| 443 // function. | 442 // function. |
| 444 size_t NextDefiningFunctionID = 0; | 443 size_t NextDefiningFunctionID = 0; |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 572 Ice::VariableDeclaration * | 571 Ice::VariableDeclaration * |
| 573 reportGetGlobalVariableByIDError(NaClBcIndexSize_t Index); | 572 reportGetGlobalVariableByIDError(NaClBcIndexSize_t Index); |
| 574 | 573 |
| 575 // Reports that there is no corresponding ICE type for LLVMTy, and returns | 574 // Reports that there is no corresponding ICE type for LLVMTy, and returns |
| 576 // Ice::IceType_void. | 575 // Ice::IceType_void. |
| 577 Ice::Type convertToIceTypeError(Type *LLVMTy); | 576 Ice::Type convertToIceTypeError(Type *LLVMTy); |
| 578 }; | 577 }; |
| 579 | 578 |
| 580 bool TopLevelParser::ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit, | 579 bool TopLevelParser::ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit, |
| 581 const std::string &Message) { | 580 const std::string &Message) { |
| 582 ErrorStatus.assign(Ice::EC_Bitcode); | |
| 583 ++NumErrors; | |
| 584 Ice::GlobalContext *Context = Translator.getContext(); | 581 Ice::GlobalContext *Context = Translator.getContext(); |
| 582 { | |
| 583 std::unique_lock<Ice::GlobalLockType> L(ErrorReportingLock); | |
|
Jim Stichnoth
2016/03/25 04:31:04
name this "_" instead of "L"?
Karl
2016/03/29 17:35:02
Done.
| |
| 584 ErrorStatus.assign(Ice::EC_Bitcode); | |
| 585 } | |
| 585 { // Lock while printing out error message. | 586 { // Lock while printing out error message. |
| 586 Ice::OstreamLocker L(Context); | 587 Ice::OstreamLocker L(Context); |
| 587 raw_ostream &OldErrStream = setErrStream(Context->getStrError()); | 588 raw_ostream &OldErrStream = setErrStream(Context->getStrError()); |
| 588 NaClBitcodeParser::ErrorAt(Level, Bit, Message); | 589 NaClBitcodeParser::ErrorAt(Level, Bit, Message); |
| 589 setErrStream(OldErrStream); | 590 setErrStream(OldErrStream); |
| 590 } | 591 } |
| 591 if (Level >= naclbitc::Error && | 592 if (Level >= naclbitc::Error && |
| 592 !Translator.getFlags().getAllowErrorRecovery()) | 593 !Translator.getFlags().getAllowErrorRecovery()) { |
| 594 Context->waitForWorkerThreads(); | |
| 593 Fatal(); | 595 Fatal(); |
| 596 } | |
| 594 return true; | 597 return true; |
| 595 } | 598 } |
| 596 | 599 |
| 597 void TopLevelParser::reportBadTypeIDAs(NaClBcIndexSize_t ID, | 600 void TopLevelParser::reportBadTypeIDAs(NaClBcIndexSize_t ID, |
| 598 const ExtendedType *Ty, | 601 const ExtendedType *Ty, |
| 599 ExtendedType::TypeKind WantedType) { | 602 ExtendedType::TypeKind WantedType) { |
| 600 std::string Buffer; | 603 std::string Buffer; |
| 601 raw_string_ostream StrBuf(Buffer); | 604 raw_string_ostream StrBuf(Buffer); |
| 602 if (Ty == nullptr) { | 605 if (Ty == nullptr) { |
| 603 StrBuf << "Can't find extended type for type id: " << ID; | 606 StrBuf << "Can't find extended type for type id: " << ID; |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 657 BlockParserBaseClass(const BlockParserBaseClass &) = delete; | 660 BlockParserBaseClass(const BlockParserBaseClass &) = delete; |
| 658 BlockParserBaseClass &operator=(const BlockParserBaseClass &) = delete; | 661 BlockParserBaseClass &operator=(const BlockParserBaseClass &) = delete; |
| 659 | 662 |
| 660 public: | 663 public: |
| 661 // Constructor for the top-level module block parser. | 664 // Constructor for the top-level module block parser. |
| 662 BlockParserBaseClass(unsigned BlockID, TopLevelParser *Context) | 665 BlockParserBaseClass(unsigned BlockID, TopLevelParser *Context) |
| 663 : NaClBitcodeParser(BlockID, Context), Context(Context) { | 666 : NaClBitcodeParser(BlockID, Context), Context(Context) { |
| 664 Context->setBlockParser(this); | 667 Context->setBlockParser(this); |
| 665 } | 668 } |
| 666 | 669 |
| 670 BlockParserBaseClass(unsigned BlockID, BlockParserBaseClass *EnclosingParser, | |
| 671 NaClBitstreamCursor &Cursor) | |
| 672 : NaClBitcodeParser(BlockID, EnclosingParser, Cursor), | |
| 673 Context(EnclosingParser->Context) {} | |
| 674 | |
| 667 ~BlockParserBaseClass() override { Context->setBlockParser(nullptr); } | 675 ~BlockParserBaseClass() override { Context->setBlockParser(nullptr); } |
| 668 | 676 |
| 669 // Returns the printable name of the type of block being parsed. | 677 // Returns the printable name of the type of block being parsed. |
| 670 virtual const char *getBlockName() const { | 678 virtual const char *getBlockName() const { |
| 671 // If this class is used, it is parsing an unknown block. | 679 // If this class is used, it is parsing an unknown block. |
| 672 return "unknown"; | 680 return "unknown"; |
| 673 } | 681 } |
| 674 | 682 |
| 675 // Generates an error Message with the Bit address prefixed to it. | 683 // Generates an error Message with the Bit address prefixed to it. |
| 676 bool ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit, | 684 bool ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit, |
| 677 const std::string &Message) final; | 685 const std::string &Message) override; |
| 678 | 686 |
| 679 protected: | 687 protected: |
| 680 // The context parser that contains the decoded state. | 688 // The context parser that contains the decoded state. |
| 681 TopLevelParser *Context; | 689 TopLevelParser *Context; |
| 690 // True if ErrorAt has been called in this block. | |
| 691 bool BlockHasError = false; | |
| 682 | 692 |
| 683 // Constructor for nested block parsers. | 693 // Constructor for nested block parsers. |
| 684 BlockParserBaseClass(unsigned BlockID, BlockParserBaseClass *EnclosingParser) | 694 BlockParserBaseClass(unsigned BlockID, BlockParserBaseClass *EnclosingParser) |
| 685 : NaClBitcodeParser(BlockID, EnclosingParser), | 695 : NaClBitcodeParser(BlockID, EnclosingParser), |
| 686 Context(EnclosingParser->Context) {} | 696 Context(EnclosingParser->Context) {} |
| 687 | 697 |
| 688 // Gets the translator associated with the bitcode parser. | 698 // Gets the translator associated with the bitcode parser. |
| 689 Ice::Translator &getTranslator() const { return Context->getTranslator(); } | 699 Ice::Translator &getTranslator() const { return Context->getTranslator(); } |
| 690 | 700 |
| 691 const Ice::ClFlags &getFlags() const { return getTranslator().getFlags(); } | 701 const Ice::ClFlags &getFlags() const { return getTranslator().getFlags(); } |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 749 bool TopLevelParser::blockError(const std::string &Message) { | 759 bool TopLevelParser::blockError(const std::string &Message) { |
| 750 if (BlockParser) | 760 if (BlockParser) |
| 751 return BlockParser->Error(Message); | 761 return BlockParser->Error(Message); |
| 752 else | 762 else |
| 753 return Error(Message); | 763 return Error(Message); |
| 754 } | 764 } |
| 755 | 765 |
| 756 // Generates an error Message with the bit address prefixed to it. | 766 // Generates an error Message with the bit address prefixed to it. |
| 757 bool BlockParserBaseClass::ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit, | 767 bool BlockParserBaseClass::ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit, |
| 758 const std::string &Message) { | 768 const std::string &Message) { |
| 769 BlockHasError = true; | |
| 759 std::string Buffer; | 770 std::string Buffer; |
| 760 raw_string_ostream StrBuf(Buffer); | 771 raw_string_ostream StrBuf(Buffer); |
| 761 // Note: If dump routines have been turned off, the error messages will not | 772 // 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 | 773 // be readable. Hence, replace with simple error. We also use the simple form |
| 763 // for unit tests. | 774 // for unit tests. |
| 764 if (getFlags().getGenerateUnitTestMessages()) { | 775 if (getFlags().getGenerateUnitTestMessages()) { |
| 765 StrBuf << "Invalid " << getBlockName() << " record: <" << Record.GetCode(); | 776 StrBuf << "Invalid " << getBlockName() << " record: <" << Record.GetCode(); |
| 766 for (const uint64_t Val : Record.GetValues()) { | 777 for (const uint64_t Val : Record.GetValues()) { |
| 767 StrBuf << " " << Val; | 778 StrBuf << " " << Val; |
| 768 } | 779 } |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 805 void BlockParserBaseClass::ProcessRecord() { | 816 void BlockParserBaseClass::ProcessRecord() { |
| 806 // If called, derived class doesn't know how to handle. | 817 // If called, derived class doesn't know how to handle. |
| 807 std::string Buffer; | 818 std::string Buffer; |
| 808 raw_string_ostream StrBuf(Buffer); | 819 raw_string_ostream StrBuf(Buffer); |
| 809 StrBuf << "Don't know how to process " << getBlockName() | 820 StrBuf << "Don't know how to process " << getBlockName() |
| 810 << " record:" << Record; | 821 << " record:" << Record; |
| 811 Error(StrBuf.str()); | 822 Error(StrBuf.str()); |
| 812 } | 823 } |
| 813 | 824 |
| 814 // Class to parse a types block. | 825 // Class to parse a types block. |
| 815 class TypesParser : public BlockParserBaseClass { | 826 class TypesParser final : public BlockParserBaseClass { |
| 816 TypesParser() = delete; | 827 TypesParser() = delete; |
| 817 TypesParser(const TypesParser &) = delete; | 828 TypesParser(const TypesParser &) = delete; |
| 818 TypesParser &operator=(const TypesParser &) = delete; | 829 TypesParser &operator=(const TypesParser &) = delete; |
| 819 | 830 |
| 820 public: | 831 public: |
| 821 TypesParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) | 832 TypesParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) |
| 822 : BlockParserBaseClass(BlockID, EnclosingParser), | 833 : BlockParserBaseClass(BlockID, EnclosingParser), |
| 823 Timer(Ice::TimerStack::TT_parseTypes, getTranslator().getContext()) {} | 834 Timer(Ice::TimerStack::TT_parseTypes, getTranslator().getContext()) {} |
| 824 | 835 |
| 825 ~TypesParser() override { | 836 ~TypesParser() override { |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1009 } | 1020 } |
| 1010 default: | 1021 default: |
| 1011 BlockParserBaseClass::ProcessRecord(); | 1022 BlockParserBaseClass::ProcessRecord(); |
| 1012 return; | 1023 return; |
| 1013 } | 1024 } |
| 1014 llvm_unreachable("Unknown type block record not processed!"); | 1025 llvm_unreachable("Unknown type block record not processed!"); |
| 1015 } | 1026 } |
| 1016 | 1027 |
| 1017 /// Parses the globals block (i.e. global variable declarations and | 1028 /// Parses the globals block (i.e. global variable declarations and |
| 1018 /// corresponding initializers). | 1029 /// corresponding initializers). |
| 1019 class GlobalsParser : public BlockParserBaseClass { | 1030 class GlobalsParser final : public BlockParserBaseClass { |
| 1020 GlobalsParser() = delete; | 1031 GlobalsParser() = delete; |
| 1021 GlobalsParser(const GlobalsParser &) = delete; | 1032 GlobalsParser(const GlobalsParser &) = delete; |
| 1022 GlobalsParser &operator=(const GlobalsParser &) = delete; | 1033 GlobalsParser &operator=(const GlobalsParser &) = delete; |
| 1023 | 1034 |
| 1024 public: | 1035 public: |
| 1025 GlobalsParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) | 1036 GlobalsParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) |
| 1026 : BlockParserBaseClass(BlockID, EnclosingParser), | 1037 : BlockParserBaseClass(BlockID, EnclosingParser), |
| 1027 Timer(Ice::TimerStack::TT_parseGlobals, getTranslator().getContext()), | 1038 Timer(Ice::TimerStack::TT_parseGlobals, getTranslator().getContext()), |
| 1028 NumFunctionIDs(Context->getNumFunctionIDs()), | 1039 NumFunctionIDs(Context->getNumFunctionIDs()), |
| 1029 DummyGlobalVar(Ice::VariableDeclaration::create( | 1040 DummyGlobalVar(Ice::VariableDeclaration::create( |
| 1030 Context->getGlobalVariablesPool())), | 1041 Context->getGlobalVariablesPool())), |
| 1031 CurGlobalVar(DummyGlobalVar) { | 1042 CurGlobalVar(DummyGlobalVar) { |
| 1032 Context->getGlobalVariablesPool()->willNotBeEmitted(DummyGlobalVar); | 1043 Context->getGlobalVariablesPool()->willNotBeEmitted(DummyGlobalVar); |
| 1033 } | 1044 } |
| 1034 | 1045 |
| 1035 ~GlobalsParser() final = default; | 1046 ~GlobalsParser() override = default; |
| 1036 | 1047 |
| 1037 const char *getBlockName() const override { return "globals"; } | 1048 const char *getBlockName() const override { return "globals"; } |
| 1038 | 1049 |
| 1039 private: | 1050 private: |
| 1040 using GlobalVarsMapType = | 1051 using GlobalVarsMapType = |
| 1041 std::unordered_map<NaClBcIndexSize_t, Ice::VariableDeclaration *>; | 1052 std::unordered_map<NaClBcIndexSize_t, Ice::VariableDeclaration *>; |
| 1042 | 1053 |
| 1043 Ice::TimerMarker Timer; | 1054 Ice::TimerMarker Timer; |
| 1044 | 1055 |
| 1045 // Holds global variables generated/referenced in the global variables block. | 1056 // Holds global variables generated/referenced in the global variables block. |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1329 } | 1340 } |
| 1330 default: | 1341 default: |
| 1331 break; | 1342 break; |
| 1332 } | 1343 } |
| 1333 // If reached, don't know how to handle record. | 1344 // If reached, don't know how to handle record. |
| 1334 BlockParserBaseClass::ProcessRecord(); | 1345 BlockParserBaseClass::ProcessRecord(); |
| 1335 return; | 1346 return; |
| 1336 } | 1347 } |
| 1337 | 1348 |
| 1338 /// Parses function blocks in the bitcode file. | 1349 /// Parses function blocks in the bitcode file. |
| 1339 class FunctionParser : public BlockParserBaseClass { | 1350 class FunctionParser final : public BlockParserBaseClass { |
| 1340 FunctionParser() = delete; | 1351 FunctionParser() = delete; |
| 1341 FunctionParser(const FunctionParser &) = delete; | 1352 FunctionParser(const FunctionParser &) = delete; |
| 1342 FunctionParser &operator=(const FunctionParser &) = delete; | 1353 FunctionParser &operator=(const FunctionParser &) = delete; |
| 1343 | 1354 |
| 1344 public: | 1355 public: |
| 1345 FunctionParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) | 1356 FunctionParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser, |
| 1357 NaClBcIndexSize_t FcnId) | |
| 1346 : BlockParserBaseClass(BlockID, EnclosingParser), | 1358 : BlockParserBaseClass(BlockID, EnclosingParser), |
| 1347 Timer(Ice::TimerStack::TT_parseFunctions, getTranslator().getContext()), | 1359 Timer(Ice::TimerStack::TT_parseFunctions, getTranslator().getContext()), |
| 1348 Func(nullptr), FcnId(Context->getNextFunctionBlockValueID()), | 1360 Func(nullptr), FuncDecl(Context->getFunctionByID(FcnId)), |
| 1349 FuncDecl(Context->getFunctionByID(FcnId)), | |
| 1350 CachedNumGlobalValueIDs(Context->getNumGlobalIDs()), | 1361 CachedNumGlobalValueIDs(Context->getNumGlobalIDs()), |
| 1351 NextLocalInstIndex(Context->getNumGlobalIDs()) {} | 1362 NextLocalInstIndex(Context->getNumGlobalIDs()) {} |
| 1352 | 1363 |
| 1353 bool convertFunction() { | 1364 FunctionParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser, |
| 1365 NaClBcIndexSize_t FcnId, NaClBitstreamCursor &Cursor) | |
| 1366 : BlockParserBaseClass(BlockID, EnclosingParser, Cursor), | |
| 1367 Timer(Ice::TimerStack::TT_parseFunctions, getTranslator().getContext()), | |
| 1368 Func(nullptr), FuncDecl(Context->getFunctionByID(FcnId)), | |
| 1369 CachedNumGlobalValueIDs(Context->getNumGlobalIDs()), | |
| 1370 NextLocalInstIndex(Context->getNumGlobalIDs()) {} | |
| 1371 | |
| 1372 std::unique_ptr<Ice::Cfg> parseFunction(uint32_t SeqNumber) { | |
| 1354 bool ParserResult; | 1373 bool ParserResult; |
| 1374 Ice::GlobalContext *Ctx = getTranslator().getContext(); | |
| 1355 { | 1375 { |
| 1356 Ice::TimerMarker T(getTranslator().getContext(), FuncDecl->getName()); | 1376 Ice::TimerMarker T(Ctx, FuncDecl->getName()); |
| 1357 // Note: The Cfg is created, even when IR generation is disabled. This is | 1377 // Note: The Cfg is created, even when IR generation is disabled. This is |
| 1358 // done to install a CfgLocalAllocator for various internal containers. | 1378 // done to install a CfgLocalAllocator for various internal containers. |
| 1359 Func = Ice::Cfg::create(getTranslator().getContext(), | 1379 Func = Ice::Cfg::create(Ctx, SeqNumber); |
| 1360 getTranslator().getNextSequenceNumber()); | |
| 1361 | 1380 |
| 1362 Ice::CfgLocalAllocatorScope _(Func.get()); | 1381 Ice::CfgLocalAllocatorScope _(Func.get()); |
| 1363 | 1382 |
| 1364 // TODO(kschimpf) Clean up API to add a function signature to a CFG. | 1383 // TODO(kschimpf) Clean up API to add a function signature to a CFG. |
| 1365 const Ice::FuncSigType &Signature = FuncDecl->getSignature(); | 1384 const Ice::FuncSigType &Signature = FuncDecl->getSignature(); |
| 1366 | 1385 |
| 1367 Func->setFunctionName(FuncDecl->getName()); | 1386 Func->setFunctionName(FuncDecl->getName()); |
| 1368 Func->setReturnType(Signature.getReturnType()); | 1387 Func->setReturnType(Signature.getReturnType()); |
| 1369 Func->setInternal(FuncDecl->getLinkage() == GlobalValue::InternalLinkage); | 1388 Func->setInternal(FuncDecl->getLinkage() == GlobalValue::InternalLinkage); |
| 1370 CurrentNode = installNextBasicBlock(); | 1389 CurrentNode = installNextBasicBlock(); |
| 1371 Func->setEntryNode(CurrentNode); | 1390 Func->setEntryNode(CurrentNode); |
| 1372 for (Ice::Type ArgType : Signature.getArgList()) { | 1391 for (Ice::Type ArgType : Signature.getArgList()) { |
| 1373 Func->addArg(getNextInstVar(ArgType)); | 1392 Func->addArg(getNextInstVar(ArgType)); |
| 1374 } | 1393 } |
| 1375 | 1394 |
| 1376 ParserResult = ParseThisBlock(); | 1395 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 } | 1396 } |
| 1389 | 1397 |
| 1390 return ParserResult; | 1398 if (ParserResult || BlockHasError) |
| 1399 Func->setError("Unable to parse function"); | |
| 1400 | |
| 1401 return std::move(Func); | |
| 1391 } | 1402 } |
| 1392 | 1403 |
| 1393 ~FunctionParser() final = default; | 1404 ~FunctionParser() override = default; |
| 1394 | 1405 |
| 1395 const char *getBlockName() const override { return "function"; } | 1406 const char *getBlockName() const override { return "function"; } |
| 1396 | 1407 |
| 1397 Ice::Cfg *getFunc() const { return Func.get(); } | 1408 Ice::Cfg *getFunc() const { return Func.get(); } |
| 1398 | 1409 |
| 1399 size_t getNumGlobalIDs() const { return CachedNumGlobalValueIDs; } | 1410 size_t getNumGlobalIDs() const { return CachedNumGlobalValueIDs; } |
| 1400 | 1411 |
| 1401 void setNextLocalInstIndex(Ice::Operand *Op) { | 1412 void setNextLocalInstIndex(Ice::Operand *Op) { |
| 1402 setOperand(NextLocalInstIndex++, Op); | 1413 setOperand(NextLocalInstIndex++, Op); |
| 1403 } | 1414 } |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 1427 // the number of bytes defining the function block. | 1438 // the number of bytes defining the function block. |
| 1428 uint64_t MaxRecordsInBlock = 0; | 1439 uint64_t MaxRecordsInBlock = 0; |
| 1429 // The corresponding ICE function defined by the function block. | 1440 // The corresponding ICE function defined by the function block. |
| 1430 std::unique_ptr<Ice::Cfg> Func; | 1441 std::unique_ptr<Ice::Cfg> Func; |
| 1431 // The index to the current basic block being built. | 1442 // The index to the current basic block being built. |
| 1432 NaClBcIndexSize_t CurrentBbIndex = 0; | 1443 NaClBcIndexSize_t CurrentBbIndex = 0; |
| 1433 // The number of basic blocks declared for the function block. | 1444 // The number of basic blocks declared for the function block. |
| 1434 NaClBcIndexSize_t DeclaredNumberBbs = 0; | 1445 NaClBcIndexSize_t DeclaredNumberBbs = 0; |
| 1435 // The basic block being built. | 1446 // The basic block being built. |
| 1436 Ice::CfgNode *CurrentNode = nullptr; | 1447 Ice::CfgNode *CurrentNode = nullptr; |
| 1437 // The ID for the function. | |
| 1438 NaClBcIndexSize_t FcnId; | |
| 1439 // The corresponding function declaration. | 1448 // The corresponding function declaration. |
| 1440 Ice::FunctionDeclaration *FuncDecl; | 1449 Ice::FunctionDeclaration *FuncDecl; |
| 1441 // Holds the dividing point between local and global absolute value indices. | 1450 // Holds the dividing point between local and global absolute value indices. |
| 1442 size_t CachedNumGlobalValueIDs; | 1451 size_t CachedNumGlobalValueIDs; |
| 1443 // Holds operands local to the function block, based on indices defined in | 1452 // Holds operands local to the function block, based on indices defined in |
| 1444 // the bitcode file. | 1453 // the bitcode file. |
| 1445 Ice::OperandList LocalOperands; | 1454 Ice::OperandList LocalOperands; |
| 1446 // Holds the index within LocalOperands corresponding to the next instruction | 1455 // Holds the index within LocalOperands corresponding to the next instruction |
| 1447 // that generates a value. | 1456 // that generates a value. |
| 1448 NaClBcIndexSize_t NextLocalInstIndex; | 1457 NaClBcIndexSize_t NextLocalInstIndex; |
| 1449 // True if the last processed instruction was a terminating instruction. | 1458 // True if the last processed instruction was a terminating instruction. |
| 1450 bool InstIsTerminating = false; | 1459 bool InstIsTerminating = false; |
| 1451 | 1460 |
| 1452 bool ParseBlock(unsigned BlockID) override; | 1461 bool ParseBlock(unsigned BlockID) override; |
| 1453 | 1462 |
| 1454 void ProcessRecord() override; | 1463 void ProcessRecord() override; |
| 1455 | 1464 |
| 1456 void EnterBlock(unsigned NumWords) final { | 1465 void EnterBlock(unsigned NumWords) override { |
| 1457 // Note: Bitstream defines words as 32-bit values. | 1466 // Note: Bitstream defines words as 32-bit values. |
| 1458 NumBytesDefiningFunction = NumWords * sizeof(uint32_t); | 1467 NumBytesDefiningFunction = NumWords * sizeof(uint32_t); |
| 1459 // We know that all records are minimally defined by a two-bit abreviation. | 1468 // We know that all records are minimally defined by a two-bit abreviation. |
| 1460 MaxRecordsInBlock = NumBytesDefiningFunction * (CHAR_BIT >> 1); | 1469 MaxRecordsInBlock = NumBytesDefiningFunction * (CHAR_BIT >> 1); |
| 1461 } | 1470 } |
| 1462 | 1471 |
| 1463 void ExitBlock() override; | 1472 void ExitBlock() override; |
| 1464 | 1473 |
| 1465 // Creates and appends a new basic block to the list of basic blocks. | 1474 // Creates and appends a new basic block to the list of basic blocks. |
| 1466 Ice::CfgNode *installNextBasicBlock() { | 1475 Ice::CfgNode *installNextBasicBlock() { |
| (...skipping 1296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2763 return; | 2772 return; |
| 2764 } | 2773 } |
| 2765 default: | 2774 default: |
| 2766 // Generate error message! | 2775 // Generate error message! |
| 2767 BlockParserBaseClass::ProcessRecord(); | 2776 BlockParserBaseClass::ProcessRecord(); |
| 2768 return; | 2777 return; |
| 2769 } | 2778 } |
| 2770 } | 2779 } |
| 2771 | 2780 |
| 2772 /// Parses constants within a function block. | 2781 /// Parses constants within a function block. |
| 2773 class ConstantsParser : public BlockParserBaseClass { | 2782 class ConstantsParser final : public BlockParserBaseClass { |
| 2774 ConstantsParser() = delete; | 2783 ConstantsParser() = delete; |
| 2775 ConstantsParser(const ConstantsParser &) = delete; | 2784 ConstantsParser(const ConstantsParser &) = delete; |
| 2776 ConstantsParser &operator=(const ConstantsParser &) = delete; | 2785 ConstantsParser &operator=(const ConstantsParser &) = delete; |
| 2777 | 2786 |
| 2778 public: | 2787 public: |
| 2779 ConstantsParser(unsigned BlockID, FunctionParser *FuncParser) | 2788 ConstantsParser(unsigned BlockID, FunctionParser *FuncParser) |
| 2780 : BlockParserBaseClass(BlockID, FuncParser), | 2789 : BlockParserBaseClass(BlockID, FuncParser), |
| 2781 Timer(Ice::TimerStack::TT_parseConstants, getTranslator().getContext()), | 2790 Timer(Ice::TimerStack::TT_parseConstants, getTranslator().getContext()), |
| 2782 FuncParser(FuncParser) {} | 2791 FuncParser(FuncParser) {} |
| 2783 | 2792 |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2880 } | 2889 } |
| 2881 } | 2890 } |
| 2882 default: | 2891 default: |
| 2883 // Generate error message! | 2892 // Generate error message! |
| 2884 BlockParserBaseClass::ProcessRecord(); | 2893 BlockParserBaseClass::ProcessRecord(); |
| 2885 return; | 2894 return; |
| 2886 } | 2895 } |
| 2887 } | 2896 } |
| 2888 | 2897 |
| 2889 // Parses valuesymtab blocks appearing in a function block. | 2898 // Parses valuesymtab blocks appearing in a function block. |
| 2890 class FunctionValuesymtabParser : public ValuesymtabParser { | 2899 class FunctionValuesymtabParser final : public ValuesymtabParser { |
| 2891 FunctionValuesymtabParser() = delete; | 2900 FunctionValuesymtabParser() = delete; |
| 2892 FunctionValuesymtabParser(const FunctionValuesymtabParser &) = delete; | 2901 FunctionValuesymtabParser(const FunctionValuesymtabParser &) = delete; |
| 2893 void operator=(const FunctionValuesymtabParser &) = delete; | 2902 void operator=(const FunctionValuesymtabParser &) = delete; |
| 2894 | 2903 |
| 2895 public: | 2904 public: |
| 2896 FunctionValuesymtabParser(unsigned BlockID, FunctionParser *EnclosingParser) | 2905 FunctionValuesymtabParser(unsigned BlockID, FunctionParser *EnclosingParser) |
| 2897 : ValuesymtabParser(BlockID, EnclosingParser), | 2906 : ValuesymtabParser(BlockID, EnclosingParser), |
| 2898 Timer(Ice::TimerStack::TT_parseFunctionValuesymtabs, | 2907 Timer(Ice::TimerStack::TT_parseFunctionValuesymtabs, |
| 2899 getTranslator().getContext()) {} | 2908 getTranslator().getContext()) {} |
| 2900 | 2909 |
| 2901 private: | 2910 private: |
| 2902 Ice::TimerMarker Timer; | 2911 Ice::TimerMarker Timer; |
| 2903 // Returns the enclosing function parser. | 2912 // Returns the enclosing function parser. |
| 2904 FunctionParser *getFunctionParser() const { | 2913 FunctionParser *getFunctionParser() const { |
| 2905 return reinterpret_cast<FunctionParser *>(GetEnclosingParser()); | 2914 return reinterpret_cast<FunctionParser *>(GetEnclosingParser()); |
| 2906 } | 2915 } |
| 2907 | 2916 |
| 2908 const char *getTableKind() const final { return "Function"; } | 2917 const char *getTableKind() const override { return "Function"; } |
| 2909 | 2918 |
| 2910 void setValueName(NaClBcIndexSize_t Index, StringType &Name) final; | 2919 void setValueName(NaClBcIndexSize_t Index, StringType &Name) override; |
| 2911 void setBbName(NaClBcIndexSize_t Index, StringType &Name) final; | 2920 void setBbName(NaClBcIndexSize_t Index, StringType &Name) override; |
| 2912 | 2921 |
| 2913 // Reports that the assignment of Name to the value associated with index is | 2922 // Reports that the assignment of Name to the value associated with index is |
| 2914 // not possible, for the given Context. | 2923 // not possible, for the given Context. |
| 2915 void reportUnableToAssign(const char *Context, NaClBcIndexSize_t Index, | 2924 void reportUnableToAssign(const char *Context, NaClBcIndexSize_t Index, |
| 2916 StringType &Name) { | 2925 StringType &Name) { |
| 2917 std::string Buffer; | 2926 std::string Buffer; |
| 2918 raw_string_ostream StrBuf(Buffer); | 2927 raw_string_ostream StrBuf(Buffer); |
| 2919 StrBuf << "Function-local " << Context << " name '" << Name | 2928 StrBuf << "Function-local " << Context << " name '" << Name |
| 2920 << "' can't be associated with index " << Index; | 2929 << "' can't be associated with index " << Index; |
| 2921 Error(StrBuf.str()); | 2930 Error(StrBuf.str()); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2967 } | 2976 } |
| 2968 break; | 2977 break; |
| 2969 } | 2978 } |
| 2970 default: | 2979 default: |
| 2971 break; | 2980 break; |
| 2972 } | 2981 } |
| 2973 return BlockParserBaseClass::ParseBlock(BlockID); | 2982 return BlockParserBaseClass::ParseBlock(BlockID); |
| 2974 } | 2983 } |
| 2975 | 2984 |
| 2976 /// Parses the module block in the bitcode file. | 2985 /// Parses the module block in the bitcode file. |
| 2977 class ModuleParser : public BlockParserBaseClass { | 2986 class ModuleParser final : public BlockParserBaseClass { |
| 2978 ModuleParser() = delete; | 2987 ModuleParser() = delete; |
| 2979 ModuleParser(const ModuleParser &) = delete; | 2988 ModuleParser(const ModuleParser &) = delete; |
| 2980 ModuleParser &operator=(const ModuleParser &) = delete; | 2989 ModuleParser &operator=(const ModuleParser &) = delete; |
| 2981 | 2990 |
| 2982 public: | 2991 public: |
| 2983 ModuleParser(unsigned BlockID, TopLevelParser *Context) | 2992 ModuleParser(unsigned BlockID, TopLevelParser *Context) |
| 2984 : BlockParserBaseClass(BlockID, Context), | 2993 : BlockParserBaseClass(BlockID, Context), |
| 2985 Timer(Ice::TimerStack::TT_parseModule, | 2994 Timer(Ice::TimerStack::TT_parseModule, |
| 2986 Context->getTranslator().getContext()) {} | 2995 Context->getTranslator().getContext()) {} |
| 2987 | |
| 2988 ~ModuleParser() override = default; | 2996 ~ModuleParser() override = default; |
| 2989 | |
| 2990 const char *getBlockName() const override { return "module"; } | 2997 const char *getBlockName() const override { return "module"; } |
| 2998 NaClBitstreamReader &getReader() const { return Record.GetReader(); } | |
| 2991 | 2999 |
| 2992 private: | 3000 private: |
| 2993 Ice::TimerMarker Timer; | 3001 Ice::TimerMarker Timer; |
| 2994 // True if we have already installed names for unnamed global declarations, | 3002 // True if we have already installed names for unnamed global declarations, |
| 2995 // and have generated global constant initializers. | 3003 // and have generated global constant initializers. |
| 2996 bool GlobalDeclarationNamesAndInitializersInstalled = false; | 3004 bool GlobalDeclarationNamesAndInitializersInstalled = false; |
| 2997 // True if we have already processed the symbol table for the module. | 3005 // True if we have already processed the symbol table for the module. |
| 2998 bool FoundValuesymtab = false; | 3006 bool FoundValuesymtab = false; |
| 2999 | 3007 |
| 3000 // Generates names for unnamed global addresses (i.e. functions and global | 3008 // Generates names for unnamed global addresses (i.e. functions and global |
| 3001 // variables). Then lowers global variable declaration initializers to the | 3009 // variables). Then lowers global variable declaration initializers to the |
| 3002 // target. May be called multiple times. Only the first call will do the | 3010 // target. May be called multiple times. Only the first call will do the |
| 3003 // installation. | 3011 // installation. |
| 3004 void installGlobalNamesAndGlobalVarInitializers() { | 3012 void installGlobalNamesAndGlobalVarInitializers() { |
| 3005 if (!GlobalDeclarationNamesAndInitializersInstalled) { | 3013 if (!GlobalDeclarationNamesAndInitializersInstalled) { |
| 3006 Context->installGlobalNames(); | 3014 Context->installGlobalNames(); |
| 3007 Context->createValueIDs(); | 3015 Context->createValueIDs(); |
| 3008 Context->verifyFunctionTypeSignatures(); | 3016 Context->verifyFunctionTypeSignatures(); |
| 3009 std::unique_ptr<Ice::VariableDeclarationList> Globals = | 3017 std::unique_ptr<Ice::VariableDeclarationList> Globals = |
| 3010 Context->getGlobalVariables(); | 3018 Context->getGlobalVariables(); |
| 3011 if (Globals) | 3019 if (Globals) |
| 3012 getTranslator().lowerGlobals(std::move(Globals)); | 3020 getTranslator().lowerGlobals(std::move(Globals)); |
| 3013 GlobalDeclarationNamesAndInitializersInstalled = true; | 3021 GlobalDeclarationNamesAndInitializersInstalled = true; |
| 3014 } | 3022 } |
| 3015 } | 3023 } |
| 3016 bool ParseBlock(unsigned BlockID) override; | 3024 bool ParseBlock(unsigned BlockID) override; |
| 3017 | 3025 |
| 3018 void ExitBlock() override { installGlobalNamesAndGlobalVarInitializers(); } | 3026 void ExitBlock() override { |
| 3027 installGlobalNamesAndGlobalVarInitializers(); | |
| 3028 Context->getTranslator().getContext()->waitForWorkerThreads(); | |
| 3029 } | |
| 3019 | 3030 |
| 3020 void ProcessRecord() override; | 3031 void ProcessRecord() override; |
| 3021 }; | 3032 }; |
| 3022 | 3033 |
| 3023 class ModuleValuesymtabParser : public ValuesymtabParser { | 3034 class ModuleValuesymtabParser : public ValuesymtabParser { |
| 3024 ModuleValuesymtabParser() = delete; | 3035 ModuleValuesymtabParser() = delete; |
| 3025 ModuleValuesymtabParser(const ModuleValuesymtabParser &) = delete; | 3036 ModuleValuesymtabParser(const ModuleValuesymtabParser &) = delete; |
| 3026 void operator=(const ModuleValuesymtabParser &) = delete; | 3037 void operator=(const ModuleValuesymtabParser &) = delete; |
| 3027 | 3038 |
| 3028 public: | 3039 public: |
| 3029 ModuleValuesymtabParser(unsigned BlockID, ModuleParser *MP) | 3040 ModuleValuesymtabParser(unsigned BlockID, ModuleParser *MP) |
| 3030 : ValuesymtabParser(BlockID, MP), | 3041 : ValuesymtabParser(BlockID, MP), |
| 3031 Timer(Ice::TimerStack::TT_parseModuleValuesymtabs, | 3042 Timer(Ice::TimerStack::TT_parseModuleValuesymtabs, |
| 3032 getTranslator().getContext()) {} | 3043 getTranslator().getContext()) {} |
| 3033 | 3044 |
| 3034 ~ModuleValuesymtabParser() override = default; | 3045 ~ModuleValuesymtabParser() override = default; |
| 3035 | 3046 |
| 3036 private: | 3047 private: |
| 3037 Ice::TimerMarker Timer; | 3048 Ice::TimerMarker Timer; |
| 3038 const char *getTableKind() const final { return "Module"; } | 3049 const char *getTableKind() const override { return "Module"; } |
| 3039 void setValueName(NaClBcIndexSize_t Index, StringType &Name) final; | 3050 void setValueName(NaClBcIndexSize_t Index, StringType &Name) override; |
| 3040 void setBbName(NaClBcIndexSize_t Index, StringType &Name) final; | 3051 void setBbName(NaClBcIndexSize_t Index, StringType &Name) override; |
| 3041 }; | 3052 }; |
| 3042 | 3053 |
| 3043 void ModuleValuesymtabParser::setValueName(NaClBcIndexSize_t Index, | 3054 void ModuleValuesymtabParser::setValueName(NaClBcIndexSize_t Index, |
| 3044 StringType &Name) { | 3055 StringType &Name) { |
| 3045 Ice::GlobalDeclaration *Decl = Context->getGlobalDeclarationByID(Index); | 3056 Ice::GlobalDeclaration *Decl = Context->getGlobalDeclarationByID(Index); |
| 3046 if (llvm::isa<Ice::VariableDeclaration>(Decl) && | 3057 if (llvm::isa<Ice::VariableDeclaration>(Decl) && |
| 3047 Decl->isPNaClABIExternalName(Name.str())) { | 3058 Decl->isPNaClABIExternalName(Name.str())) { |
| 3048 // Force linkage of (specific) Global Variables be external for the PNaCl | 3059 // Force linkage of (specific) Global Variables be external for the PNaCl |
| 3049 // ABI. PNaCl bitcode has a linkage field for Functions, but not for | 3060 // ABI. PNaCl bitcode has a linkage field for Functions, but not for |
| 3050 // GlobalVariables (because the latter is not needed for pexes, so it has | 3061 // GlobalVariables (because the latter is not needed for pexes, so it has |
| 3051 // been removed). | 3062 // been removed). |
| 3052 Decl->setLinkage(llvm::GlobalValue::ExternalLinkage); | 3063 Decl->setLinkage(llvm::GlobalValue::ExternalLinkage); |
| 3053 } | 3064 } |
| 3054 | 3065 |
| 3055 Decl->setName(StringRef(Name.data(), Name.size())); | 3066 Decl->setName(StringRef(Name.data(), Name.size())); |
| 3056 } | 3067 } |
| 3057 | 3068 |
| 3058 void ModuleValuesymtabParser::setBbName(NaClBcIndexSize_t Index, | 3069 void ModuleValuesymtabParser::setBbName(NaClBcIndexSize_t Index, |
| 3059 StringType &Name) { | 3070 StringType &Name) { |
| 3060 reportUnableToAssign("Basic block", Index, Name); | 3071 reportUnableToAssign("Basic block", Index, Name); |
| 3061 } | 3072 } |
| 3062 | 3073 |
| 3074 class CfgParserWorkItem final : public Ice::OptWorkItem { | |
| 3075 CfgParserWorkItem() = delete; | |
| 3076 CfgParserWorkItem(const CfgParserWorkItem &) = delete; | |
| 3077 CfgParserWorkItem &operator=(const CfgParserWorkItem &) = delete; | |
| 3078 | |
| 3079 public: | |
| 3080 CfgParserWorkItem(unsigned BlockID, NaClBcIndexSize_t FcnId, | |
| 3081 ModuleParser *ModParser, uint64_t StartBit, | |
| 3082 uint32_t SeqNumber) | |
| 3083 : BlockID(BlockID), FcnId(FcnId), ModParser(ModParser), | |
| 3084 StartBit(StartBit), SeqNumber(SeqNumber) {} | |
| 3085 std::unique_ptr<Ice::Cfg> getParsedCfg() override { | |
| 3086 NaClBitstreamCursor Cursor(ModParser->getReader()); | |
| 3087 Cursor.JumpToBit(StartBit); | |
| 3088 FunctionParser Parser(BlockID, const_cast<ModuleParser *>(ModParser), FcnId, | |
| 3089 Cursor); | |
| 3090 return Parser.parseFunction(SeqNumber); | |
| 3091 } | |
| 3092 ~CfgParserWorkItem() override = default; | |
| 3093 | |
| 3094 private: | |
| 3095 const unsigned BlockID; | |
| 3096 const NaClBcIndexSize_t FcnId; | |
| 3097 const ModuleParser *ModParser; | |
| 3098 const uint64_t StartBit; | |
| 3099 const uint32_t SeqNumber; | |
| 3100 }; | |
| 3101 | |
| 3063 bool ModuleParser::ParseBlock(unsigned BlockID) { | 3102 bool ModuleParser::ParseBlock(unsigned BlockID) { |
| 3064 switch (BlockID) { | 3103 switch (BlockID) { |
| 3065 case naclbitc::BLOCKINFO_BLOCK_ID: | 3104 case naclbitc::BLOCKINFO_BLOCK_ID: |
| 3066 return NaClBitcodeParser::ParseBlock(BlockID); | 3105 return NaClBitcodeParser::ParseBlock(BlockID); |
| 3067 case naclbitc::TYPE_BLOCK_ID_NEW: { | 3106 case naclbitc::TYPE_BLOCK_ID_NEW: { |
| 3068 TypesParser Parser(BlockID, this); | 3107 TypesParser Parser(BlockID, this); |
| 3069 return Parser.ParseThisBlock(); | 3108 return Parser.ParseThisBlock(); |
| 3070 } | 3109 } |
| 3071 case naclbitc::GLOBALVAR_BLOCK_ID: { | 3110 case naclbitc::GLOBALVAR_BLOCK_ID: { |
| 3072 GlobalsParser Parser(BlockID, this); | 3111 GlobalsParser Parser(BlockID, this); |
| 3073 return Parser.ParseThisBlock(); | 3112 return Parser.ParseThisBlock(); |
| 3074 } | 3113 } |
| 3075 case naclbitc::VALUE_SYMTAB_BLOCK_ID: { | 3114 case naclbitc::VALUE_SYMTAB_BLOCK_ID: { |
| 3076 if (FoundValuesymtab) | 3115 if (FoundValuesymtab) |
| 3077 Fatal("Duplicate valuesymtab in module"); | 3116 Fatal("Duplicate valuesymtab in module"); |
| 3078 | 3117 |
| 3079 // If we have already processed a function block (i.e. we have already | 3118 // If we have already processed a function block (i.e. we have already |
| 3080 // installed global names and variable initializers) we can no longer accept | 3119 // installed global names and variable initializers) we can no longer accept |
| 3081 // the value symbol table. Names have already been generated. | 3120 // the value symbol table. Names have already been generated. |
| 3082 if (GlobalDeclarationNamesAndInitializersInstalled) | 3121 if (GlobalDeclarationNamesAndInitializersInstalled) |
| 3083 Fatal("Module valuesymtab not allowed after function blocks"); | 3122 Fatal("Module valuesymtab not allowed after function blocks"); |
| 3084 | 3123 |
| 3085 FoundValuesymtab = true; | 3124 FoundValuesymtab = true; |
| 3086 ModuleValuesymtabParser Parser(BlockID, this); | 3125 ModuleValuesymtabParser Parser(BlockID, this); |
| 3087 return Parser.ParseThisBlock(); | 3126 return Parser.ParseThisBlock(); |
| 3088 } | 3127 } |
| 3089 case naclbitc::FUNCTION_BLOCK_ID: { | 3128 case naclbitc::FUNCTION_BLOCK_ID: { |
| 3090 installGlobalNamesAndGlobalVarInitializers(); | 3129 installGlobalNamesAndGlobalVarInitializers(); |
| 3091 FunctionParser Parser(BlockID, this); | 3130 Ice::GlobalContext *Ctx = Context->getTranslator().getContext(); |
| 3092 return Parser.convertFunction(); | 3131 uint32_t SeqNumber = Context->getTranslator().getNextSequenceNumber(); |
| 3132 NaClBcIndexSize_t FcnId = Context->getNextFunctionBlockValueID(); | |
| 3133 if (Ctx->getFlags().getParseParallel()) { | |
| 3134 uint64_t StartBit = Record.GetCursor().GetCurrentBitNo(); | |
| 3135 if (SkipBlock()) | |
| 3136 return true; | |
| 3137 Ice::GlobalContext *Ctx = Context->getTranslator().getContext(); | |
| 3138 Ctx->optQueueBlockingPush(Ice::makeUnique<CfgParserWorkItem>( | |
| 3139 BlockID, FcnId, this, StartBit, SeqNumber)); | |
| 3140 return false; | |
| 3141 } else { | |
| 3142 FunctionParser Parser(BlockID, this, FcnId); | |
| 3143 std::unique_ptr<Ice::Cfg> Func = Parser.parseFunction(SeqNumber); | |
| 3144 bool Failed = Func->hasError(); | |
| 3145 getTranslator().translateFcn(std::move(Func)); | |
| 3146 return Failed && !getTranslator().getFlags().getAllowErrorRecovery(); | |
| 3147 } | |
| 3093 } | 3148 } |
| 3094 default: | 3149 default: |
| 3095 return BlockParserBaseClass::ParseBlock(BlockID); | 3150 return BlockParserBaseClass::ParseBlock(BlockID); |
| 3096 } | 3151 } |
| 3097 } | 3152 } |
| 3098 | 3153 |
| 3099 void ModuleParser::ProcessRecord() { | 3154 void ModuleParser::ProcessRecord() { |
| 3100 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); | 3155 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); |
| 3101 switch (Record.GetCode()) { | 3156 switch (Record.GetCode()) { |
| 3102 case naclbitc::MODULE_CODE_VERSION: { | 3157 case naclbitc::MODULE_CODE_VERSION: { |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3177 std::unique_ptr<MemoryObject> &&MemObj) { | 3232 std::unique_ptr<MemoryObject> &&MemObj) { |
| 3178 // On error, we report_fatal_error to avoid destroying the MemObj. That may | 3233 // On error, we report_fatal_error to avoid destroying the MemObj. That may |
| 3179 // still be in use by IceBrowserCompileServer. Otherwise, we need to change | 3234 // still be in use by IceBrowserCompileServer. Otherwise, we need to change |
| 3180 // the MemObj to be ref-counted, or have a wrapper, or simply leak. We also | 3235 // the MemObj to be ref-counted, or have a wrapper, or simply leak. We also |
| 3181 // need a hook to tell the IceBrowserCompileServer to unblock its | 3236 // need a hook to tell the IceBrowserCompileServer to unblock its |
| 3182 // QueueStreamer. | 3237 // QueueStreamer. |
| 3183 // https://code.google.com/p/nativeclient/issues/detail?id=4163 | 3238 // https://code.google.com/p/nativeclient/issues/detail?id=4163 |
| 3184 // Read header and verify it is good. | 3239 // Read header and verify it is good. |
| 3185 NaClBitcodeHeader Header; | 3240 NaClBitcodeHeader Header; |
| 3186 if (Header.Read(MemObj.get())) { | 3241 if (Header.Read(MemObj.get())) { |
| 3242 getContext()->waitForWorkerThreads(); | |
| 3187 llvm::report_fatal_error("Invalid PNaCl bitcode header"); | 3243 llvm::report_fatal_error("Invalid PNaCl bitcode header"); |
| 3188 } | 3244 } |
| 3189 if (!Header.IsSupported()) { | 3245 if (!Header.IsSupported()) { |
| 3190 getContext()->getStrError() << Header.Unsupported(); | 3246 getContext()->getStrError() << Header.Unsupported(); |
| 3191 if (!Header.IsReadable()) { | 3247 if (!Header.IsReadable()) { |
| 3248 getContext()->waitForWorkerThreads(); | |
| 3192 llvm::report_fatal_error("Invalid PNaCl bitcode header"); | 3249 llvm::report_fatal_error("Invalid PNaCl bitcode header"); |
| 3193 } | 3250 } |
| 3194 } | 3251 } |
| 3195 | 3252 |
| 3196 // Create a bitstream reader to read the bitcode file. | 3253 // Create a bitstream reader to read the bitcode file. |
| 3197 NaClBitstreamReader InputStreamFile(MemObj.release(), Header); | 3254 NaClBitstreamReader InputStreamFile(MemObj.release(), Header); |
| 3198 NaClBitstreamCursor InputStream(InputStreamFile); | 3255 NaClBitstreamCursor InputStream(InputStreamFile); |
| 3199 | 3256 |
| 3200 TopLevelParser Parser(*this, InputStream, ErrorStatus); | 3257 TopLevelParser Parser(*this, InputStream, ErrorStatus); |
| 3201 while (!InputStream.AtEndOfStream()) { | 3258 while (!InputStream.AtEndOfStream()) { |
| 3202 if (Parser.Parse()) { | 3259 if (Parser.Parse()) { |
| 3260 getContext()->waitForWorkerThreads(); | |
| 3203 ErrorStatus.assign(EC_Bitcode); | 3261 ErrorStatus.assign(EC_Bitcode); |
| 3204 return; | 3262 return; |
| 3205 } | 3263 } |
| 3206 } | 3264 } |
| 3207 | 3265 |
| 3208 if (!Parser.parsedModuleBlock()) { | 3266 if (!Parser.parsedModuleBlock()) { |
| 3267 getContext()->waitForWorkerThreads(); | |
| 3209 std::string Buffer; | 3268 std::string Buffer; |
| 3210 raw_string_ostream StrBuf(Buffer); | 3269 raw_string_ostream StrBuf(Buffer); |
| 3211 StrBuf << IRFilename << ": Does not contain a module!"; | 3270 StrBuf << IRFilename << ": Does not contain a module!"; |
| 3212 llvm::report_fatal_error(StrBuf.str()); | 3271 llvm::report_fatal_error(StrBuf.str()); |
| 3213 } | 3272 } |
| 3214 if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) { | 3273 if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) { |
| 3274 getContext()->waitForWorkerThreads(); | |
| 3215 llvm::report_fatal_error("Bitcode stream should be a multiple of 4 bytes"); | 3275 llvm::report_fatal_error("Bitcode stream should be a multiple of 4 bytes"); |
| 3216 } | 3276 } |
| 3217 } | 3277 } |
| 3218 | 3278 |
| 3219 } // end of namespace Ice | 3279 } // end of namespace Ice |
| OLD | NEW |