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