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 989 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1000 assert(Op); | 1000 assert(Op); |
1001 // Check if simple push works. | 1001 // Check if simple push works. |
1002 uint32_t LocalIndex = Index - CachedNumGlobalValueIDs; | 1002 uint32_t LocalIndex = Index - CachedNumGlobalValueIDs; |
1003 if (LocalIndex == LocalOperands.size()) { | 1003 if (LocalIndex == LocalOperands.size()) { |
1004 LocalOperands.push_back(Op); | 1004 LocalOperands.push_back(Op); |
1005 return; | 1005 return; |
1006 } | 1006 } |
1007 | 1007 |
1008 // Must be forward reference, expand vector to accommodate. | 1008 // Must be forward reference, expand vector to accommodate. |
1009 if (LocalIndex >= LocalOperands.size()) | 1009 if (LocalIndex >= LocalOperands.size()) |
1010 LocalOperands.resize(LocalIndex+1); | 1010 LocalOperands.resize(LocalIndex + 1); |
1011 | 1011 |
1012 // If element not defined, set it. | 1012 // If element not defined, set it. |
1013 Ice::Operand *OldOp = LocalOperands[LocalIndex]; | 1013 Ice::Operand *OldOp = LocalOperands[LocalIndex]; |
1014 if (OldOp == NULL) { | 1014 if (OldOp == NULL) { |
1015 LocalOperands[LocalIndex] = Op; | 1015 LocalOperands[LocalIndex] = Op; |
1016 return; | 1016 return; |
1017 } | 1017 } |
1018 | 1018 |
1019 // See if forward reference matches. | 1019 // See if forward reference matches. |
1020 if (OldOp == Op) | 1020 if (OldOp == Op) |
1021 return; | 1021 return; |
1022 | 1022 |
1023 // Error has occurred. | 1023 // Error has occurred. |
1024 std::string Buffer; | 1024 std::string Buffer; |
1025 raw_string_ostream StrBuf(Buffer); | 1025 raw_string_ostream StrBuf(Buffer); |
1026 StrBuf << "Multiple definitions for index " << Index | 1026 StrBuf << "Multiple definitions for index " << Index << ": " << *Op |
1027 << ": " << *Op << " and " << *OldOp; | 1027 << " and " << *OldOp; |
1028 Error(StrBuf.str()); | 1028 Error(StrBuf.str()); |
1029 // TODO(kschimpf) Remove error recovery once implementation complete. | 1029 // TODO(kschimpf) Remove error recovery once implementation complete. |
1030 LocalOperands[LocalIndex] = Op; | 1030 LocalOperands[LocalIndex] = Op; |
1031 } | 1031 } |
1032 | 1032 |
1033 // Returns the relative operand (wrt to BaseIndex) referenced by | 1033 // Returns the relative operand (wrt to BaseIndex) referenced by |
1034 // the given value Index. | 1034 // the given value Index. |
1035 Ice::Operand *getRelativeOperand(int32_t Index, int32_t BaseIndex) { | 1035 Ice::Operand *getRelativeOperand(int32_t Index, int32_t BaseIndex) { |
1036 return getOperand(convertRelativeToAbsIndex(Index, BaseIndex)); | 1036 return getOperand(convertRelativeToAbsIndex(Index, BaseIndex)); |
1037 } | 1037 } |
1038 | 1038 |
1039 // Returns the absolute index of the next value generating instruction. | 1039 // Returns the absolute index of the next value generating instruction. |
1040 uint32_t getNextInstIndex() const { | 1040 uint32_t getNextInstIndex() const { return NextLocalInstIndex; } |
1041 return NextLocalInstIndex; | |
1042 } | |
1043 | 1041 |
1044 // Generates type error message for binary operator Op | 1042 // Generates type error message for binary operator Op |
1045 // operating on Type OpTy. | 1043 // operating on Type OpTy. |
1046 void ReportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy); | 1044 void ReportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy); |
1047 | 1045 |
1048 // Validates if integer logical Op, for type OpTy, is valid. | 1046 // Validates if integer logical Op, for type OpTy, is valid. |
1049 // Returns true if valid. Otherwise generates error message and | 1047 // Returns true if valid. Otherwise generates error message and |
1050 // returns false. | 1048 // returns false. |
1051 bool isValidIntegerLogicalOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) { | 1049 bool isValidIntegerLogicalOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) { |
1052 if (Ice::isIntegerType(OpTy)) | 1050 if (Ice::isIntegerType(OpTy)) |
(...skipping 622 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1675 Ice::CfgNode *ThenBlock = getBranchBasicBlock(Values[0]); | 1673 Ice::CfgNode *ThenBlock = getBranchBasicBlock(Values[0]); |
1676 Ice::CfgNode *ElseBlock = getBranchBasicBlock(Values[1]); | 1674 Ice::CfgNode *ElseBlock = getBranchBasicBlock(Values[1]); |
1677 if (ThenBlock == NULL || ElseBlock == NULL) | 1675 if (ThenBlock == NULL || ElseBlock == NULL) |
1678 return; | 1676 return; |
1679 CurrentNode->appendInst( | 1677 CurrentNode->appendInst( |
1680 Ice::InstBr::create(Func, Cond, ThenBlock, ElseBlock)); | 1678 Ice::InstBr::create(Func, Cond, ThenBlock, ElseBlock)); |
1681 } | 1679 } |
1682 InstIsTerminating = true; | 1680 InstIsTerminating = true; |
1683 break; | 1681 break; |
1684 } | 1682 } |
| 1683 case naclbitc::FUNC_CODE_INST_SWITCH: { |
| 1684 // SWITCH: [Condty, Cond, BbIndex, NumCases Case ...] |
| 1685 // where Case = [1, 1, Value, BbIndex]. |
| 1686 // |
| 1687 // Note: Unlike most instructions, we don't infer the type of |
| 1688 // Cond, but provide it as a separate field. There are also |
| 1689 // unnecesary data fields (i.e. constants 1). These were not |
| 1690 // cleaned up in PNaCl bitcode because the bitcode format was |
| 1691 // already frozen when the problem was noticed. |
| 1692 if (!isValidRecordSizeAtLeast(4, "function block switch")) |
| 1693 return; |
| 1694 Ice::Type CondTy = |
| 1695 Context->convertToIceType(Context->getTypeByID(Values[0])); |
| 1696 if (!Ice::isScalarIntegerType(CondTy)) { |
| 1697 std::string Buffer; |
| 1698 raw_string_ostream StrBuf(Buffer); |
| 1699 StrBuf << "Case condition must be non-wide integer. Found: " << CondTy; |
| 1700 Error(StrBuf.str()); |
| 1701 return; |
| 1702 } |
| 1703 Ice::SizeT BitWidth = Ice::getScalarIntBitWidth(CondTy); |
| 1704 Ice::Operand *Cond = getRelativeOperand(Values[1], BaseIndex); |
| 1705 if (CondTy != Cond->getType()) { |
| 1706 std::string Buffer; |
| 1707 raw_string_ostream StrBuf(Buffer); |
| 1708 StrBuf << "Case condition expects type " << CondTy |
| 1709 << ". Found: " << Cond->getType(); |
| 1710 Error(StrBuf.str()); |
| 1711 return; |
| 1712 } |
| 1713 Ice::CfgNode *DefaultLabel = getBranchBasicBlock(Values[2]); |
| 1714 unsigned NumCases = Values[3]; |
| 1715 |
| 1716 // Now recognize each of the cases. |
| 1717 if (!isValidRecordSize(4 + NumCases * 4, "Function block switch")) |
| 1718 return; |
| 1719 Ice::InstSwitch *Switch = |
| 1720 Ice::InstSwitch::create(Func, NumCases, Cond, DefaultLabel); |
| 1721 unsigned ValCaseIndex = 4; // index to beginning of case entry. |
| 1722 for (unsigned CaseIndex = 0; CaseIndex < NumCases; |
| 1723 ++CaseIndex, ValCaseIndex += 4) { |
| 1724 if (Values[ValCaseIndex] != 1 || Values[ValCaseIndex+1] != 1) { |
| 1725 std::string Buffer; |
| 1726 raw_string_ostream StrBuf(Buffer); |
| 1727 StrBuf << "Sequence [1, 1, value, label] expected for case entry " |
| 1728 << "in switch record. (at index" << ValCaseIndex << ")"; |
| 1729 Error(StrBuf.str()); |
| 1730 return; |
| 1731 } |
| 1732 APInt Value(BitWidth, |
| 1733 NaClDecodeSignRotatedValue(Values[ValCaseIndex + 2]), |
| 1734 true); |
| 1735 Ice::CfgNode *Label = getBranchBasicBlock(Values[ValCaseIndex + 3]); |
| 1736 Switch->addBranch(CaseIndex, Value.getSExtValue(), Label); |
| 1737 } |
| 1738 CurrentNode->appendInst(Switch); |
| 1739 InstIsTerminating = true; |
| 1740 break; |
| 1741 } |
1685 case naclbitc::FUNC_CODE_INST_UNREACHABLE: { | 1742 case naclbitc::FUNC_CODE_INST_UNREACHABLE: { |
1686 // UNREACHABLE: [] | 1743 // UNREACHABLE: [] |
1687 if (!isValidRecordSize(0, "function block unreachable")) | 1744 if (!isValidRecordSize(0, "function block unreachable")) |
1688 return; | 1745 return; |
1689 CurrentNode->appendInst( | 1746 CurrentNode->appendInst( |
1690 Ice::InstUnreachable::create(Func)); | 1747 Ice::InstUnreachable::create(Func)); |
1691 InstIsTerminating = true; | 1748 InstIsTerminating = true; |
1692 break; | 1749 break; |
1693 } | 1750 } |
1694 case naclbitc::FUNC_CODE_INST_PHI: { | 1751 case naclbitc::FUNC_CODE_INST_PHI: { |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1774 if (!isValidLoadStoreAlignment(Alignment, Value->getType(), "Store")) | 1831 if (!isValidLoadStoreAlignment(Alignment, Value->getType(), "Store")) |
1775 return; | 1832 return; |
1776 CurrentNode->appendInst( | 1833 CurrentNode->appendInst( |
1777 Ice::InstStore::create(Func, Value, Address, Alignment)); | 1834 Ice::InstStore::create(Func, Value, Address, Alignment)); |
1778 break; | 1835 break; |
1779 } | 1836 } |
1780 case naclbitc::FUNC_CODE_INST_FORWARDTYPEREF: { | 1837 case naclbitc::FUNC_CODE_INST_FORWARDTYPEREF: { |
1781 // FORWARDTYPEREF: [opval, ty] | 1838 // FORWARDTYPEREF: [opval, ty] |
1782 if (!isValidRecordSize(2, "function block forward type ref")) | 1839 if (!isValidRecordSize(2, "function block forward type ref")) |
1783 return; | 1840 return; |
1784 setOperand(Values[0], createInstVar( | 1841 setOperand(Values[0], createInstVar(Context->convertToIceType( |
1785 Context->convertToIceType(Context->getTypeByID(Values[1])))); | 1842 Context->getTypeByID(Values[1])))); |
1786 break; | 1843 break; |
1787 } | 1844 } |
1788 case naclbitc::FUNC_CODE_INST_SWITCH: | |
1789 case naclbitc::FUNC_CODE_INST_CALL: | 1845 case naclbitc::FUNC_CODE_INST_CALL: |
1790 case naclbitc::FUNC_CODE_INST_CALL_INDIRECT: | 1846 case naclbitc::FUNC_CODE_INST_CALL_INDIRECT: |
1791 default: | 1847 default: |
1792 // Generate error message! | 1848 // Generate error message! |
1793 BlockParserBaseClass::ProcessRecord(); | 1849 BlockParserBaseClass::ProcessRecord(); |
1794 break; | 1850 break; |
1795 } | 1851 } |
1796 } | 1852 } |
1797 | 1853 |
1798 /// Parses constants within a function block. | 1854 /// Parses constants within a function block. |
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2188 if (TopLevelBlocks != 1) { | 2244 if (TopLevelBlocks != 1) { |
2189 errs() << IRFilename | 2245 errs() << IRFilename |
2190 << ": Contains more than one module. Found: " << TopLevelBlocks | 2246 << ": Contains more than one module. Found: " << TopLevelBlocks |
2191 << "\n"; | 2247 << "\n"; |
2192 ErrorStatus = true; | 2248 ErrorStatus = true; |
2193 } | 2249 } |
2194 return; | 2250 return; |
2195 } | 2251 } |
2196 | 2252 |
2197 } // end of namespace Ice | 2253 } // end of namespace Ice |
OLD | NEW |