Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(81)

Side by Side Diff: src/PNaClTranslator.cpp

Issue 576243002: Add switch instruction to Subzero bitcode reader. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix issues in patch set 2. Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/IceTypes.cpp ('k') | tests_lit/reader_tests/switch.ll » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/IceTypes.cpp ('k') | tests_lit/reader_tests/switch.ll » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698