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 // This file implements the PNaCl bitcode file to Ice, to machine code | 10 // This file implements the PNaCl bitcode file to Ice, to machine code |
(...skipping 714 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
725 default: | 725 default: |
726 BlockParserBaseClass::ProcessRecord(); | 726 BlockParserBaseClass::ProcessRecord(); |
727 return; | 727 return; |
728 } | 728 } |
729 // If reached, just processed another initializer. See if time | 729 // If reached, just processed another initializer. See if time |
730 // to install global. | 730 // to install global. |
731 if (InitializersNeeded == Initializers.size()) | 731 if (InitializersNeeded == Initializers.size()) |
732 installGlobalVar(); | 732 installGlobalVar(); |
733 } | 733 } |
734 | 734 |
735 // Parses a valuesymtab block in the bitcode file. | 735 /// Base class for parsing a valuesymtab block in the bitcode file. |
736 class ValuesymtabParser : public BlockParserBaseClass { | 736 class ValuesymtabParser : public BlockParserBaseClass { |
737 typedef SmallString<128> StringType; | 737 ValuesymtabParser(const ValuesymtabParser &) LLVM_DELETED_FUNCTION; |
| 738 void operator=(const ValuesymtabParser &) LLVM_DELETED_FUNCTION; |
738 | 739 |
739 public: | 740 public: |
740 ValuesymtabParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser, | 741 ValuesymtabParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) |
741 bool AllowBbEntries) | 742 : BlockParserBaseClass(BlockID, EnclosingParser) {} |
742 : BlockParserBaseClass(BlockID, EnclosingParser), | |
743 AllowBbEntries(AllowBbEntries) {} | |
744 | 743 |
745 virtual ~ValuesymtabParser() LLVM_OVERRIDE {} | 744 virtual ~ValuesymtabParser() LLVM_OVERRIDE {} |
746 | 745 |
| 746 protected: |
| 747 typedef SmallString<128> StringType; |
| 748 |
| 749 // Associates Name with the value defined by the given Index. |
| 750 virtual void setValueName(uint64_t Index, StringType &Name) = 0; |
| 751 |
| 752 // Associates Name with the value defined by the given Index; |
| 753 virtual void setBbName(uint64_t Index, StringType &Name) = 0; |
| 754 |
747 private: | 755 private: |
748 // True if entries to name basic blocks allowed. | |
749 bool AllowBbEntries; | |
750 | 756 |
751 virtual void ProcessRecord() LLVM_OVERRIDE; | 757 virtual void ProcessRecord() LLVM_OVERRIDE; |
752 | 758 |
753 void ConvertToString(StringType &ConvertedName) { | 759 void ConvertToString(StringType &ConvertedName) { |
754 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); | 760 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); |
755 for (size_t i = 1, e = Values.size(); i != e; ++i) { | 761 for (size_t i = 1, e = Values.size(); i != e; ++i) { |
756 ConvertedName += static_cast<char>(Values[i]); | 762 ConvertedName += static_cast<char>(Values[i]); |
757 } | 763 } |
758 } | 764 } |
759 }; | 765 }; |
760 | 766 |
761 void ValuesymtabParser::ProcessRecord() { | 767 void ValuesymtabParser::ProcessRecord() { |
762 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); | 768 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); |
763 StringType ConvertedName; | 769 StringType ConvertedName; |
764 switch (Record.GetCode()) { | 770 switch (Record.GetCode()) { |
765 case naclbitc::VST_CODE_ENTRY: { | 771 case naclbitc::VST_CODE_ENTRY: { |
766 // VST_ENTRY: [ValueId, namechar x N] | 772 // VST_ENTRY: [ValueId, namechar x N] |
767 if (!isValidRecordSizeAtLeast(2, "Valuesymtab value entry")) | 773 if (!isValidRecordSizeAtLeast(2, "Valuesymtab value entry")) |
768 return; | 774 return; |
769 ConvertToString(ConvertedName); | 775 ConvertToString(ConvertedName); |
770 Value *V = Context->getGlobalValueByID(Values[0]); | 776 setValueName(Values[0], ConvertedName); |
771 if (V == NULL) { | |
772 std::string Buffer; | |
773 raw_string_ostream StrBuf(Buffer); | |
774 StrBuf << "Invalid global address ID in valuesymtab: " << Values[0]; | |
775 Error(StrBuf.str()); | |
776 return; | |
777 } | |
778 V->setName(StringRef(ConvertedName.data(), ConvertedName.size())); | |
779 return; | 777 return; |
780 } | 778 } |
781 case naclbitc::VST_CODE_BBENTRY: { | 779 case naclbitc::VST_CODE_BBENTRY: { |
782 // VST_BBENTRY: [BbId, namechar x N] | 780 // VST_BBENTRY: [BbId, namechar x N] |
783 // For now, since we aren't processing function blocks, don't handle. | 781 if (!isValidRecordSizeAtLeast(2, "Valuesymtab basic block entry")) |
784 if (AllowBbEntries) { | |
785 Error("Valuesymtab bb entry not implemented"); | |
786 return; | 782 return; |
787 } | 783 ConvertToString(ConvertedName); |
788 break; | 784 setBbName(Values[0], ConvertedName); |
| 785 return; |
789 } | 786 } |
790 default: | 787 default: |
791 break; | 788 break; |
792 } | 789 } |
793 // If reached, don't know how to handle record. | 790 // If reached, don't know how to handle record. |
794 BlockParserBaseClass::ProcessRecord(); | 791 BlockParserBaseClass::ProcessRecord(); |
795 return; | 792 return; |
796 } | 793 } |
797 | 794 |
| 795 class FunctionValuesymtabParser; |
| 796 |
798 /// Parses function blocks in the bitcode file. | 797 /// Parses function blocks in the bitcode file. |
799 class FunctionParser : public BlockParserBaseClass { | 798 class FunctionParser : public BlockParserBaseClass { |
800 FunctionParser(const FunctionParser &) LLVM_DELETED_FUNCTION; | 799 FunctionParser(const FunctionParser &) LLVM_DELETED_FUNCTION; |
801 FunctionParser &operator=(const FunctionParser &) LLVM_DELETED_FUNCTION; | 800 FunctionParser &operator=(const FunctionParser &) LLVM_DELETED_FUNCTION; |
| 801 friend class FunctionValuesymtabParser; |
802 | 802 |
803 public: | 803 public: |
804 FunctionParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) | 804 FunctionParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) |
805 : BlockParserBaseClass(BlockID, EnclosingParser), | 805 : BlockParserBaseClass(BlockID, EnclosingParser), |
806 Func(new Ice::Cfg(getTranslator().getContext())), CurrentBbIndex(0), | 806 Func(new Ice::Cfg(getTranslator().getContext())), CurrentBbIndex(0), |
807 FcnId(Context->getNextFunctionBlockValueID()), | 807 FcnId(Context->getNextFunctionBlockValueID()), |
808 LLVMFunc(cast<Function>(Context->getGlobalValueByID(FcnId))), | 808 LLVMFunc(cast<Function>(Context->getGlobalValueByID(FcnId))), |
809 CachedNumGlobalValueIDs(Context->getNumGlobalValueIDs()), | 809 CachedNumGlobalValueIDs(Context->getNumGlobalValueIDs()), |
810 InstIsTerminating(false) { | 810 InstIsTerminating(false) { |
811 Func->setFunctionName(LLVMFunc->getName()); | 811 Func->setFunctionName(LLVMFunc->getName()); |
812 Func->setReturnType(Context->convertToIceType(LLVMFunc->getReturnType())); | 812 Func->setReturnType(Context->convertToIceType(LLVMFunc->getReturnType())); |
813 Func->setInternal(LLVMFunc->hasInternalLinkage()); | 813 Func->setInternal(LLVMFunc->hasInternalLinkage()); |
814 CurrentNode = InstallNextBasicBlock(); | 814 CurrentNode = InstallNextBasicBlock(); |
| 815 Func->setEntryNode(CurrentNode); |
815 for (Function::const_arg_iterator ArgI = LLVMFunc->arg_begin(), | 816 for (Function::const_arg_iterator ArgI = LLVMFunc->arg_begin(), |
816 ArgE = LLVMFunc->arg_end(); | 817 ArgE = LLVMFunc->arg_end(); |
817 ArgI != ArgE; ++ArgI) { | 818 ArgI != ArgE; ++ArgI) { |
818 Func->addArg(NextInstVar(Context->convertToIceType(ArgI->getType()))); | 819 Func->addArg(NextInstVar(Context->convertToIceType(ArgI->getType()))); |
819 } | 820 } |
820 } | 821 } |
821 | 822 |
822 ~FunctionParser() LLVM_OVERRIDE; | 823 ~FunctionParser() LLVM_OVERRIDE; |
823 | 824 |
824 // Set the next constant ID to the given constant C. | 825 // Set the next constant ID to the given constant C. |
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1215 Ice::CfgNode *Node = *Iter; | 1216 Ice::CfgNode *Node = *Iter; |
1216 if (Node->getInsts().size() == 0) { | 1217 if (Node->getInsts().size() == 0) { |
1217 std::string Buffer; | 1218 std::string Buffer; |
1218 raw_string_ostream StrBuf(Buffer); | 1219 raw_string_ostream StrBuf(Buffer); |
1219 StrBuf << "Basic block " << Index << " contains no instructions"; | 1220 StrBuf << "Basic block " << Index << " contains no instructions"; |
1220 Error(StrBuf.str()); | 1221 Error(StrBuf.str()); |
1221 // TODO(kschimpf) Remove error recovery once implementation complete. | 1222 // TODO(kschimpf) Remove error recovery once implementation complete. |
1222 Node->appendInst(Ice::InstUnreachable::create(Func)); | 1223 Node->appendInst(Ice::InstUnreachable::create(Func)); |
1223 } | 1224 } |
1224 } | 1225 } |
| 1226 Func->computePredecessors(); |
1225 // Note: Once any errors have been found, we turn off all | 1227 // Note: Once any errors have been found, we turn off all |
1226 // translation of all remaining functions. This allows use to see | 1228 // translation of all remaining functions. This allows use to see |
1227 // multiple errors, without adding extra checks to the translator | 1229 // multiple errors, without adding extra checks to the translator |
1228 // for such parsing errors. | 1230 // for such parsing errors. |
1229 if (Context->getNumErrors() == 0) | 1231 if (Context->getNumErrors() == 0) |
1230 getTranslator().translateFcn(Func); | 1232 getTranslator().translateFcn(Func); |
1231 } | 1233 } |
1232 | 1234 |
1233 void FunctionParser::ReportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op, | 1235 void FunctionParser::ReportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op, |
1234 Ice::Type OpTy) { | 1236 Ice::Type OpTy) { |
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1660 } | 1662 } |
1661 } | 1663 } |
1662 } | 1664 } |
1663 default: | 1665 default: |
1664 // Generate error message! | 1666 // Generate error message! |
1665 BlockParserBaseClass::ProcessRecord(); | 1667 BlockParserBaseClass::ProcessRecord(); |
1666 return; | 1668 return; |
1667 } | 1669 } |
1668 } | 1670 } |
1669 | 1671 |
| 1672 // Parses valuesymtab blocks appearing in a function block. |
| 1673 class FunctionValuesymtabParser : public ValuesymtabParser { |
| 1674 FunctionValuesymtabParser(const FunctionValuesymtabParser &) |
| 1675 LLVM_DELETED_FUNCTION; |
| 1676 void operator=(const FunctionValuesymtabParser &) LLVM_DELETED_FUNCTION; |
| 1677 |
| 1678 public: |
| 1679 FunctionValuesymtabParser(unsigned BlockID, FunctionParser *EnclosingParser) |
| 1680 : ValuesymtabParser(BlockID, EnclosingParser) {} |
| 1681 |
| 1682 private: |
| 1683 // Returns the enclosing function parser. |
| 1684 FunctionParser *getFunctionParser() const { |
| 1685 return reinterpret_cast<FunctionParser *>(GetEnclosingParser()); |
| 1686 } |
| 1687 |
| 1688 virtual void setValueName(uint64_t Index, StringType &Name) LLVM_OVERRIDE; |
| 1689 virtual void setBbName(uint64_t Index, StringType &Name) LLVM_OVERRIDE; |
| 1690 |
| 1691 // Reports that the assignment of Name to the value associated with |
| 1692 // index is not possible, for the given Context. |
| 1693 void reportUnableToAssign(const char *Context, uint64_t Index, |
| 1694 StringType &Name) { |
| 1695 std::string Buffer; |
| 1696 raw_string_ostream StrBuf(Buffer); |
| 1697 StrBuf << "Function-local " << Context << " name '" << Name |
| 1698 << "' can't be associated with index " << Index; |
| 1699 Error(StrBuf.str()); |
| 1700 } |
| 1701 }; |
| 1702 |
| 1703 void FunctionValuesymtabParser::setValueName(uint64_t Index, StringType &Name) { |
| 1704 // Note: We check when Index is too small, so that we can error recover |
| 1705 // (FP->getOperand will create fatal error). |
| 1706 if (Index < getFunctionParser()->CachedNumGlobalValueIDs) { |
| 1707 reportUnableToAssign("instruction", Index, Name); |
| 1708 // TODO(kschimpf) Remove error recovery once implementation complete. |
| 1709 return; |
| 1710 } |
| 1711 Ice::Operand *Op = getFunctionParser()->getOperand(Index); |
| 1712 if (Ice::Variable *V = dyn_cast<Ice::Variable>(Op)) { |
| 1713 std::string Nm(Name.data(), Name.size()); |
| 1714 V->setName(Nm); |
| 1715 } else { |
| 1716 reportUnableToAssign("variable", Index, Name); |
| 1717 } |
| 1718 } |
| 1719 |
| 1720 void FunctionValuesymtabParser::setBbName(uint64_t Index, StringType &Name) { |
| 1721 if (Index >= getFunctionParser()->Func->getNumNodes()) { |
| 1722 reportUnableToAssign("block", Index, Name); |
| 1723 return; |
| 1724 } |
| 1725 std::string Nm(Name.data(), Name.size()); |
| 1726 getFunctionParser()->Func->getNodes()[Index]->setName(Nm); |
| 1727 } |
| 1728 |
1670 bool FunctionParser::ParseBlock(unsigned BlockID) { | 1729 bool FunctionParser::ParseBlock(unsigned BlockID) { |
1671 switch (BlockID) { | 1730 switch (BlockID) { |
1672 case naclbitc::CONSTANTS_BLOCK_ID: { | 1731 case naclbitc::CONSTANTS_BLOCK_ID: { |
1673 ConstantsParser Parser(BlockID, this); | 1732 ConstantsParser Parser(BlockID, this); |
1674 return Parser.ParseThisBlock(); | 1733 return Parser.ParseThisBlock(); |
1675 } | 1734 } |
| 1735 case naclbitc::VALUE_SYMTAB_BLOCK_ID: { |
| 1736 if (PNaClAllowLocalSymbolTables) { |
| 1737 FunctionValuesymtabParser Parser(BlockID, this); |
| 1738 return Parser.ParseThisBlock(); |
| 1739 } |
| 1740 break; |
| 1741 } |
1676 default: | 1742 default: |
1677 return BlockParserBaseClass::ParseBlock(BlockID); | 1743 break; |
1678 } | 1744 } |
| 1745 return BlockParserBaseClass::ParseBlock(BlockID); |
1679 } | 1746 } |
1680 | 1747 |
1681 /// Parses the module block in the bitcode file. | 1748 /// Parses the module block in the bitcode file. |
1682 class ModuleParser : public BlockParserBaseClass { | 1749 class ModuleParser : public BlockParserBaseClass { |
1683 public: | 1750 public: |
1684 ModuleParser(unsigned BlockID, TopLevelParser *Context) | 1751 ModuleParser(unsigned BlockID, TopLevelParser *Context) |
1685 : BlockParserBaseClass(BlockID, Context) {} | 1752 : BlockParserBaseClass(BlockID, Context) {} |
1686 | 1753 |
1687 virtual ~ModuleParser() LLVM_OVERRIDE {} | 1754 virtual ~ModuleParser() LLVM_OVERRIDE {} |
1688 | 1755 |
1689 protected: | 1756 protected: |
1690 virtual bool ParseBlock(unsigned BlockID) LLVM_OVERRIDE; | 1757 virtual bool ParseBlock(unsigned BlockID) LLVM_OVERRIDE; |
1691 | 1758 |
1692 virtual void ProcessRecord() LLVM_OVERRIDE; | 1759 virtual void ProcessRecord() LLVM_OVERRIDE; |
1693 }; | 1760 }; |
1694 | 1761 |
| 1762 class ModuleValuesymtabParser : public ValuesymtabParser { |
| 1763 ModuleValuesymtabParser(const ModuleValuesymtabParser &) |
| 1764 LLVM_DELETED_FUNCTION; |
| 1765 void operator=(const ModuleValuesymtabParser &) LLVM_DELETED_FUNCTION; |
| 1766 |
| 1767 public: |
| 1768 ModuleValuesymtabParser(unsigned BlockID, ModuleParser *MP) |
| 1769 : ValuesymtabParser(BlockID, MP) {} |
| 1770 |
| 1771 virtual ~ModuleValuesymtabParser() LLVM_OVERRIDE {} |
| 1772 |
| 1773 private: |
| 1774 virtual void setValueName(uint64_t Index, StringType &Name) LLVM_OVERRIDE; |
| 1775 virtual void setBbName(uint64_t Index, StringType &Name) LLVM_OVERRIDE; |
| 1776 }; |
| 1777 |
| 1778 void ModuleValuesymtabParser::setValueName(uint64_t Index, StringType &Name) { |
| 1779 Value *V = Context->getGlobalValueByID(Index); |
| 1780 if (V == NULL) { |
| 1781 std::string Buffer; |
| 1782 raw_string_ostream StrBuf(Buffer); |
| 1783 StrBuf << "Invalid global address ID in valuesymtab: " << Index; |
| 1784 Error(StrBuf.str()); |
| 1785 return; |
| 1786 } |
| 1787 V->setName(StringRef(Name.data(), Name.size())); |
| 1788 } |
| 1789 |
| 1790 void ModuleValuesymtabParser::setBbName(uint64_t Index, StringType &Name) { |
| 1791 std::string Buffer; |
| 1792 raw_string_ostream StrBuf(Buffer); |
| 1793 StrBuf << "Can't define basic block name at global level: '" << Name |
| 1794 << "' -> " << Index; |
| 1795 Error(StrBuf.str()); |
| 1796 } |
| 1797 |
1695 bool ModuleParser::ParseBlock(unsigned BlockID) LLVM_OVERRIDE { | 1798 bool ModuleParser::ParseBlock(unsigned BlockID) LLVM_OVERRIDE { |
1696 switch (BlockID) { | 1799 switch (BlockID) { |
1697 case naclbitc::BLOCKINFO_BLOCK_ID: | 1800 case naclbitc::BLOCKINFO_BLOCK_ID: |
1698 return NaClBitcodeParser::ParseBlock(BlockID); | 1801 return NaClBitcodeParser::ParseBlock(BlockID); |
1699 case naclbitc::TYPE_BLOCK_ID_NEW: { | 1802 case naclbitc::TYPE_BLOCK_ID_NEW: { |
1700 TypesParser Parser(BlockID, this); | 1803 TypesParser Parser(BlockID, this); |
1701 return Parser.ParseThisBlock(); | 1804 return Parser.ParseThisBlock(); |
1702 } | 1805 } |
1703 case naclbitc::GLOBALVAR_BLOCK_ID: { | 1806 case naclbitc::GLOBALVAR_BLOCK_ID: { |
1704 GlobalsParser Parser(BlockID, this); | 1807 GlobalsParser Parser(BlockID, this); |
1705 return Parser.ParseThisBlock(); | 1808 return Parser.ParseThisBlock(); |
1706 } | 1809 } |
1707 case naclbitc::VALUE_SYMTAB_BLOCK_ID: { | 1810 case naclbitc::VALUE_SYMTAB_BLOCK_ID: { |
1708 ValuesymtabParser Parser(BlockID, this, false); | 1811 ModuleValuesymtabParser Parser(BlockID, this); |
1709 return Parser.ParseThisBlock(); | 1812 return Parser.ParseThisBlock(); |
1710 } | 1813 } |
1711 case naclbitc::FUNCTION_BLOCK_ID: { | 1814 case naclbitc::FUNCTION_BLOCK_ID: { |
1712 FunctionParser Parser(BlockID, this); | 1815 FunctionParser Parser(BlockID, this); |
1713 return Parser.ParseThisBlock(); | 1816 return Parser.ParseThisBlock(); |
1714 } | 1817 } |
1715 default: | 1818 default: |
1716 return BlockParserBaseClass::ParseBlock(BlockID); | 1819 return BlockParserBaseClass::ParseBlock(BlockID); |
1717 } | 1820 } |
1718 } | 1821 } |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1836 if (TopLevelBlocks != 1) { | 1939 if (TopLevelBlocks != 1) { |
1837 errs() << IRFilename | 1940 errs() << IRFilename |
1838 << ": Contains more than one module. Found: " << TopLevelBlocks | 1941 << ": Contains more than one module. Found: " << TopLevelBlocks |
1839 << "\n"; | 1942 << "\n"; |
1840 ErrorStatus = true; | 1943 ErrorStatus = true; |
1841 } | 1944 } |
1842 return; | 1945 return; |
1843 } | 1946 } |
1844 | 1947 |
1845 } // end of namespace Ice | 1948 } // end of namespace Ice |
OLD | NEW |