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])); | |
Jim Stichnoth
2014/09/17 20:18:20
Consider defining "unsigned ValIndex = 0;" up here
Karl
2014/09/17 22:07:19
To try and make things clearer, I renamed ValIndex
| |
1696 if (!Ice::isScalarIntegerType(CondTy) || CondTy == Ice::IceType_i64) { | |
Jim Stichnoth
2014/09/17 20:18:20
You can have a switch on an i64 type.
Karl
2014/09/17 22:07:18
Done.
| |
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 if (!isValidRecordSize(4 + NumCases * 4, "Function block switch")) | |
1716 return; | |
1717 Ice::InstSwitch *Switch = | |
1718 Ice::InstSwitch::create(Func, NumCases, Cond, DefaultLabel); | |
1719 unsigned ValIndex = 4; | |
1720 for (unsigned CaseIndex = 0; CaseIndex < NumCases; ++CaseIndex) { | |
1721 if (Values[ValIndex] != 1) { | |
Jim Stichnoth
2014/09/17 20:18:20
(continuing comment from line 1695)
ValIndex can
Karl
2014/09/17 22:07:19
See comment above.
| |
1722 std::string Buffer; | |
1723 raw_string_ostream StrBuf(Buffer); | |
1724 StrBuf << "1 is expected for Values[" << ValIndex | |
1725 << "] in switch record. Found: " << Values[ValIndex]; | |
1726 Error(StrBuf.str()); | |
1727 return; | |
1728 } | |
1729 if (Values[++ValIndex] != 1) { | |
Jim Stichnoth
2014/09/17 20:18:20
Can this error test be combined with above? E.g.
Karl
2014/09/17 22:07:19
Done.
| |
1730 std::string Buffer; | |
1731 raw_string_ostream StrBuf(Buffer); | |
1732 StrBuf << "1 is expected for Values[" << ValIndex | |
1733 << "] in switch record. Found: " << Values[ValIndex]; | |
1734 Error(StrBuf.str()); | |
1735 return; | |
1736 } | |
1737 APInt Value(BitWidth, NaClDecodeSignRotatedValue(Values[++ValIndex]), | |
1738 true); | |
1739 Ice::CfgNode *Label = getBranchBasicBlock(Values[++ValIndex]); | |
1740 Switch->addBranch(CaseIndex, Value.getSExtValue(), Label); | |
1741 ++ValIndex; | |
Jim Stichnoth
2014/09/17 20:18:20
(continuing comment from line 1721)
and this ++Va
Karl
2014/09/17 22:07:19
Removed.
| |
1742 } | |
1743 CurrentNode->appendInst(Switch); | |
1744 InstIsTerminating = true; | |
1745 break; | |
1746 } | |
1685 case naclbitc::FUNC_CODE_INST_UNREACHABLE: { | 1747 case naclbitc::FUNC_CODE_INST_UNREACHABLE: { |
1686 // UNREACHABLE: [] | 1748 // UNREACHABLE: [] |
1687 if (!isValidRecordSize(0, "function block unreachable")) | 1749 if (!isValidRecordSize(0, "function block unreachable")) |
1688 return; | 1750 return; |
1689 CurrentNode->appendInst( | 1751 CurrentNode->appendInst( |
1690 Ice::InstUnreachable::create(Func)); | 1752 Ice::InstUnreachable::create(Func)); |
1691 InstIsTerminating = true; | 1753 InstIsTerminating = true; |
1692 break; | 1754 break; |
1693 } | 1755 } |
1694 case naclbitc::FUNC_CODE_INST_PHI: { | 1756 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")) | 1836 if (!isValidLoadStoreAlignment(Alignment, Value->getType(), "Store")) |
1775 return; | 1837 return; |
1776 CurrentNode->appendInst( | 1838 CurrentNode->appendInst( |
1777 Ice::InstStore::create(Func, Value, Address, Alignment)); | 1839 Ice::InstStore::create(Func, Value, Address, Alignment)); |
1778 break; | 1840 break; |
1779 } | 1841 } |
1780 case naclbitc::FUNC_CODE_INST_FORWARDTYPEREF: { | 1842 case naclbitc::FUNC_CODE_INST_FORWARDTYPEREF: { |
1781 // FORWARDTYPEREF: [opval, ty] | 1843 // FORWARDTYPEREF: [opval, ty] |
1782 if (!isValidRecordSize(2, "function block forward type ref")) | 1844 if (!isValidRecordSize(2, "function block forward type ref")) |
1783 return; | 1845 return; |
1784 setOperand(Values[0], createInstVar( | 1846 setOperand(Values[0], createInstVar(Context->convertToIceType( |
1785 Context->convertToIceType(Context->getTypeByID(Values[1])))); | 1847 Context->getTypeByID(Values[1])))); |
1786 break; | 1848 break; |
1787 } | 1849 } |
1788 case naclbitc::FUNC_CODE_INST_SWITCH: | |
1789 case naclbitc::FUNC_CODE_INST_CALL: | 1850 case naclbitc::FUNC_CODE_INST_CALL: |
1790 case naclbitc::FUNC_CODE_INST_CALL_INDIRECT: | 1851 case naclbitc::FUNC_CODE_INST_CALL_INDIRECT: |
1791 default: | 1852 default: |
1792 // Generate error message! | 1853 // Generate error message! |
1793 BlockParserBaseClass::ProcessRecord(); | 1854 BlockParserBaseClass::ProcessRecord(); |
1794 break; | 1855 break; |
1795 } | 1856 } |
1796 } | 1857 } |
1797 | 1858 |
1798 /// Parses constants within a function block. | 1859 /// Parses constants within a function block. |
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2188 if (TopLevelBlocks != 1) { | 2249 if (TopLevelBlocks != 1) { |
2189 errs() << IRFilename | 2250 errs() << IRFilename |
2190 << ": Contains more than one module. Found: " << TopLevelBlocks | 2251 << ": Contains more than one module. Found: " << TopLevelBlocks |
2191 << "\n"; | 2252 << "\n"; |
2192 ErrorStatus = true; | 2253 ErrorStatus = true; |
2193 } | 2254 } |
2194 return; | 2255 return; |
2195 } | 2256 } |
2196 | 2257 |
2197 } // end of namespace Ice | 2258 } // end of namespace Ice |
OLD | NEW |