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