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 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
54 ExtendedType &operator=(const ExtendedType &Ty) = delete; | 54 ExtendedType &operator=(const ExtendedType &Ty) = delete; |
55 public: | 55 public: |
56 /// Discriminator for LLVM-style RTTI. | 56 /// Discriminator for LLVM-style RTTI. |
57 enum TypeKind { Undefined, Simple, FuncSig }; | 57 enum TypeKind { Undefined, Simple, FuncSig }; |
58 | 58 |
59 ExtendedType() : Kind(Undefined) {} | 59 ExtendedType() : Kind(Undefined) {} |
60 | 60 |
61 virtual ~ExtendedType() {} | 61 virtual ~ExtendedType() {} |
62 | 62 |
63 ExtendedType::TypeKind getKind() const { return Kind; } | 63 ExtendedType::TypeKind getKind() const { return Kind; } |
64 void Dump(Ice::Ostream &Stream) const; | 64 void dump(Ice::Ostream &Stream) const; |
65 | 65 |
66 /// Changes the extended type to a simple type with the given | 66 /// Changes the extended type to a simple type with the given |
67 /// value. | 67 /// value. |
68 void setAsSimpleType(Ice::Type Ty) { | 68 void setAsSimpleType(Ice::Type Ty) { |
69 assert(Kind == Undefined); | 69 assert(Kind == Undefined); |
70 Kind = Simple; | 70 Kind = Simple; |
71 Signature.setReturnType(Ty); | 71 Signature.setReturnType(Ty); |
72 } | 72 } |
73 | 73 |
74 /// Changes the extended type to an (empty) function signature type. | 74 /// Changes the extended type to an (empty) function signature type. |
75 void setAsFunctionType() { | 75 void setAsFunctionType() { |
76 assert(Kind == Undefined); | 76 assert(Kind == Undefined); |
77 Kind = FuncSig; | 77 Kind = FuncSig; |
78 } | 78 } |
79 | 79 |
80 protected: | 80 protected: |
81 // Note: For simple types, the return type of the signature will | 81 // Note: For simple types, the return type of the signature will |
82 // be used to hold the simple type. | 82 // be used to hold the simple type. |
83 Ice::FuncSigType Signature; | 83 Ice::FuncSigType Signature; |
84 | 84 |
85 private: | 85 private: |
86 ExtendedType::TypeKind Kind; | 86 ExtendedType::TypeKind Kind; |
87 }; | 87 }; |
88 | 88 |
89 Ice::Ostream &operator<<(Ice::Ostream &Stream, const ExtendedType &Ty) { | 89 Ice::Ostream &operator<<(Ice::Ostream &Stream, const ExtendedType &Ty) { |
90 Ty.Dump(Stream); | 90 Ty.dump(Stream); |
91 return Stream; | 91 return Stream; |
92 } | 92 } |
93 | 93 |
94 Ice::Ostream &operator<<(Ice::Ostream &Stream, ExtendedType::TypeKind Kind) { | 94 Ice::Ostream &operator<<(Ice::Ostream &Stream, ExtendedType::TypeKind Kind) { |
95 Stream << "ExtendedType::"; | 95 Stream << "ExtendedType::"; |
96 switch (Kind) { | 96 switch (Kind) { |
97 case ExtendedType::Undefined: | 97 case ExtendedType::Undefined: |
98 Stream << "Undefined"; | 98 Stream << "Undefined"; |
99 break; | 99 break; |
100 case ExtendedType::Simple: | 100 case ExtendedType::Simple: |
(...skipping 29 matching lines...) Expand all Loading... |
130 const Ice::FuncSigType &getSignature() const { return Signature; } | 130 const Ice::FuncSigType &getSignature() const { return Signature; } |
131 void setReturnType(Ice::Type ReturnType) { | 131 void setReturnType(Ice::Type ReturnType) { |
132 Signature.setReturnType(ReturnType); | 132 Signature.setReturnType(ReturnType); |
133 } | 133 } |
134 void appendArgType(Ice::Type ArgType) { Signature.appendArgType(ArgType); } | 134 void appendArgType(Ice::Type ArgType) { Signature.appendArgType(ArgType); } |
135 static bool classof(const ExtendedType *Ty) { | 135 static bool classof(const ExtendedType *Ty) { |
136 return Ty->getKind() == FuncSig; | 136 return Ty->getKind() == FuncSig; |
137 } | 137 } |
138 }; | 138 }; |
139 | 139 |
140 void ExtendedType::Dump(Ice::Ostream &Stream) const { | 140 void ExtendedType::dump(Ice::Ostream &Stream) const { |
141 Stream << Kind; | 141 Stream << Kind; |
142 switch (Kind) { | 142 switch (Kind) { |
143 case Simple: { | 143 case Simple: { |
144 Stream << " " << Signature.getReturnType(); | 144 Stream << " " << Signature.getReturnType(); |
145 break; | 145 break; |
146 } | 146 } |
147 case FuncSig: { | 147 case FuncSig: { |
148 Stream << " " << Signature; | 148 Stream << " " << Signature; |
149 } | 149 } |
150 default: | 150 default: |
(...skipping 1158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1309 Context->convertToLLVMType(Ty))) | 1309 Context->convertToLLVMType(Ty))) |
1310 return true; | 1310 return true; |
1311 std::string Buffer; | 1311 std::string Buffer; |
1312 raw_string_ostream StrBuf(Buffer); | 1312 raw_string_ostream StrBuf(Buffer); |
1313 StrBuf << InstructionName << " " << Ty << "*: not allowed for alignment " | 1313 StrBuf << InstructionName << " " << Ty << "*: not allowed for alignment " |
1314 << Alignment; | 1314 << Alignment; |
1315 Error(StrBuf.str()); | 1315 Error(StrBuf.str()); |
1316 return false; | 1316 return false; |
1317 } | 1317 } |
1318 | 1318 |
| 1319 // Types of errors that can occur for insertelement and extractelement |
| 1320 // instructions. |
| 1321 enum VectorIndexCheckValue { |
| 1322 VectorIndexNotVector, |
| 1323 VectorIndexNotConstant, |
| 1324 VectorIndexNotInRange, |
| 1325 VectorIndexNotI32, |
| 1326 VectorIndexValid |
| 1327 }; |
| 1328 |
| 1329 void dumpVectorIndexCheckValue(raw_ostream &Stream, |
| 1330 VectorIndexCheckValue Value) const { |
| 1331 switch (Value) { |
| 1332 default: |
| 1333 report_fatal_error("Unknown VectorIndexCheckValue"); |
| 1334 break; |
| 1335 case VectorIndexNotVector: |
| 1336 Stream << "Vector index on non vector"; |
| 1337 break; |
| 1338 case VectorIndexNotConstant: |
| 1339 Stream << "Vector index not integer constant"; |
| 1340 break; |
| 1341 case VectorIndexNotInRange: |
| 1342 Stream << "Vector index not in range of vector"; |
| 1343 break; |
| 1344 case VectorIndexNotI32: |
| 1345 Stream << "Vector index not of type " << Ice::IceType_i32; |
| 1346 break; |
| 1347 case VectorIndexValid: |
| 1348 Stream << "Valid vector index"; |
| 1349 break; |
| 1350 } |
| 1351 } |
| 1352 |
| 1353 // Returns whether the given vector index (for insertelement and |
| 1354 // extractelement instructions) is valid. |
| 1355 VectorIndexCheckValue validateVectorIndex(const Ice::Operand *Vec, |
| 1356 const Ice::Operand *Index) const { |
| 1357 Ice::Type VecType = Vec->getType(); |
| 1358 if (!Ice::isVectorType(VecType)) |
| 1359 return VectorIndexNotVector; |
| 1360 const auto *C = dyn_cast<Ice::ConstantInteger32>(Index); |
| 1361 if (C == nullptr) |
| 1362 return VectorIndexNotConstant; |
| 1363 if (C->getValue() >= typeNumElements(VecType)) |
| 1364 return VectorIndexNotInRange; |
| 1365 if (Index->getType() != Ice::IceType_i32) |
| 1366 return VectorIndexNotI32; |
| 1367 return VectorIndexValid; |
| 1368 } |
| 1369 |
1319 // Reports that the given binary Opcode, for the given type Ty, | 1370 // Reports that the given binary Opcode, for the given type Ty, |
1320 // is not understood. | 1371 // is not understood. |
1321 void ReportInvalidBinopOpcode(unsigned Opcode, Ice::Type Ty); | 1372 void ReportInvalidBinopOpcode(unsigned Opcode, Ice::Type Ty); |
1322 | 1373 |
1323 // Returns true if the Str begins with Prefix. | 1374 // Returns true if the Str begins with Prefix. |
1324 bool isStringPrefix(Ice::IceString &Str, Ice::IceString &Prefix) { | 1375 bool isStringPrefix(Ice::IceString &Str, Ice::IceString &Prefix) { |
1325 const size_t PrefixSize = Prefix.size(); | 1376 const size_t PrefixSize = Prefix.size(); |
1326 if (Str.size() < PrefixSize) | 1377 if (Str.size() < PrefixSize) |
1327 return false; | 1378 return false; |
1328 for (size_t i = 0; i < PrefixSize; ++i) { | 1379 for (size_t i = 0; i < PrefixSize; ++i) { |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1541 case naclbitc::FCMP_UNE: | 1592 case naclbitc::FCMP_UNE: |
1542 Cond = Ice::InstFcmp::Une; | 1593 Cond = Ice::InstFcmp::Une; |
1543 return true; | 1594 return true; |
1544 case naclbitc::FCMP_TRUE: | 1595 case naclbitc::FCMP_TRUE: |
1545 Cond = Ice::InstFcmp::True; | 1596 Cond = Ice::InstFcmp::True; |
1546 return true; | 1597 return true; |
1547 default: | 1598 default: |
1548 return false; | 1599 return false; |
1549 } | 1600 } |
1550 } | 1601 } |
| 1602 |
| 1603 // Creates an error instruction, generating a value of type Ty, and |
| 1604 // adds a placeholder so that instruction indices line up. |
| 1605 // Some instructions, such as a call, will not generate a value |
| 1606 // if the return type is void. In such cases, a placeholder value |
| 1607 // for the badly formed instruction is not needed. Hence, if Ty is |
| 1608 // void, an error instruction is not appended. |
| 1609 // TODO(kschimpf) Remove error recovery once implementation complete. |
| 1610 void appendErrorInstruction(Ice::Type Ty) { |
| 1611 // Note: we don't worry about downstream translation errors because |
| 1612 // the function will not be translated if any errors occur. |
| 1613 if (Ty == Ice::IceType_void) |
| 1614 return; |
| 1615 Ice::Variable *Var = getNextInstVar(Ty); |
| 1616 CurrentNode->appendInst(Ice::InstAssign::create(Func, Var, Var)); |
| 1617 } |
1551 }; | 1618 }; |
1552 | 1619 |
1553 void FunctionParser::ReportInvalidBinopOpcode(unsigned Opcode, Ice::Type Ty) { | 1620 void FunctionParser::ReportInvalidBinopOpcode(unsigned Opcode, Ice::Type Ty) { |
1554 std::string Buffer; | 1621 std::string Buffer; |
1555 raw_string_ostream StrBuf(Buffer); | 1622 raw_string_ostream StrBuf(Buffer); |
1556 StrBuf << "Binary opcode " << Opcode << "not understood for type " << Ty; | 1623 StrBuf << "Binary opcode " << Opcode << "not understood for type " << Ty; |
1557 Error(StrBuf.str()); | 1624 Error(StrBuf.str()); |
1558 } | 1625 } |
1559 | 1626 |
1560 void FunctionParser::ExitBlock() { | 1627 void FunctionParser::ExitBlock() { |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1615 uint32_t NumBbs = Values[0]; | 1682 uint32_t NumBbs = Values[0]; |
1616 if (NumBbs == 0) { | 1683 if (NumBbs == 0) { |
1617 Error("Functions must contain at least one basic block."); | 1684 Error("Functions must contain at least one basic block."); |
1618 // TODO(kschimpf) Remove error recovery once implementation complete. | 1685 // TODO(kschimpf) Remove error recovery once implementation complete. |
1619 NumBbs = 1; | 1686 NumBbs = 1; |
1620 } | 1687 } |
1621 // Install the basic blocks, skipping bb0 which was created in the | 1688 // Install the basic blocks, skipping bb0 which was created in the |
1622 // constructor. | 1689 // constructor. |
1623 for (size_t i = 1; i < NumBbs; ++i) | 1690 for (size_t i = 1; i < NumBbs; ++i) |
1624 InstallNextBasicBlock(); | 1691 InstallNextBasicBlock(); |
1625 break; | 1692 return; |
1626 } | 1693 } |
1627 case naclbitc::FUNC_CODE_INST_BINOP: { | 1694 case naclbitc::FUNC_CODE_INST_BINOP: { |
1628 // BINOP: [opval, opval, opcode] | 1695 // BINOP: [opval, opval, opcode] |
1629 if (!isValidRecordSize(3, "function block binop")) | 1696 if (!isValidRecordSize(3, "function block binop")) |
1630 return; | 1697 return; |
1631 Ice::Operand *Op1 = getRelativeOperand(Values[0], BaseIndex); | 1698 Ice::Operand *Op1 = getRelativeOperand(Values[0], BaseIndex); |
1632 Ice::Operand *Op2 = getRelativeOperand(Values[1], BaseIndex); | 1699 Ice::Operand *Op2 = getRelativeOperand(Values[1], BaseIndex); |
1633 Ice::Type Type1 = Op1->getType(); | 1700 Ice::Type Type1 = Op1->getType(); |
1634 Ice::Type Type2 = Op2->getType(); | 1701 Ice::Type Type2 = Op2->getType(); |
1635 if (Type1 != Type2) { | 1702 if (Type1 != Type2) { |
1636 std::string Buffer; | 1703 std::string Buffer; |
1637 raw_string_ostream StrBuf(Buffer); | 1704 raw_string_ostream StrBuf(Buffer); |
1638 StrBuf << "Binop argument types differ: " << Type1 << " and " << Type2; | 1705 StrBuf << "Binop argument types differ: " << Type1 << " and " << Type2; |
1639 Error(StrBuf.str()); | 1706 Error(StrBuf.str()); |
1640 // TODO(kschimpf) Remove error recovery once implementation complete. | 1707 appendErrorInstruction(Type1); |
1641 Op2 = Op1; | 1708 return; |
1642 } | 1709 } |
1643 | 1710 |
1644 Ice::InstArithmetic::OpKind Opcode; | 1711 Ice::InstArithmetic::OpKind Opcode; |
1645 if (!convertBinopOpcode(Values[2], Type1, Opcode)) | 1712 if (!convertBinopOpcode(Values[2], Type1, Opcode)) |
1646 return; | 1713 return; |
1647 CurrentNode->appendInst(Ice::InstArithmetic::create( | 1714 CurrentNode->appendInst(Ice::InstArithmetic::create( |
1648 Func, Opcode, getNextInstVar(Type1), Op1, Op2)); | 1715 Func, Opcode, getNextInstVar(Type1), Op1, Op2)); |
1649 break; | 1716 return; |
1650 } | 1717 } |
1651 case naclbitc::FUNC_CODE_INST_CAST: { | 1718 case naclbitc::FUNC_CODE_INST_CAST: { |
1652 // CAST: [opval, destty, castopc] | 1719 // CAST: [opval, destty, castopc] |
1653 if (!isValidRecordSize(3, "function block cast")) | 1720 if (!isValidRecordSize(3, "function block cast")) |
1654 return; | 1721 return; |
1655 Ice::Operand *Src = getRelativeOperand(Values[0], BaseIndex); | 1722 Ice::Operand *Src = getRelativeOperand(Values[0], BaseIndex); |
1656 Ice::Type CastType = Context->getSimpleTypeByID(Values[1]); | 1723 Ice::Type CastType = Context->getSimpleTypeByID(Values[1]); |
1657 Instruction::CastOps LLVMCastOp; | 1724 Instruction::CastOps LLVMCastOp; |
1658 Ice::InstCast::OpKind CastKind; | 1725 Ice::InstCast::OpKind CastKind; |
1659 if (!naclbitc::DecodeCastOpcode(Values[2], LLVMCastOp) || | 1726 if (!naclbitc::DecodeCastOpcode(Values[2], LLVMCastOp) || |
1660 !convertLLVMCastOpToIceOp(LLVMCastOp, CastKind)) { | 1727 !convertLLVMCastOpToIceOp(LLVMCastOp, CastKind)) { |
1661 std::string Buffer; | 1728 std::string Buffer; |
1662 raw_string_ostream StrBuf(Buffer); | 1729 raw_string_ostream StrBuf(Buffer); |
1663 StrBuf << "Cast opcode not understood: " << Values[2]; | 1730 StrBuf << "Cast opcode not understood: " << Values[2]; |
1664 Error(StrBuf.str()); | 1731 Error(StrBuf.str()); |
| 1732 appendErrorInstruction(CastType); |
1665 return; | 1733 return; |
1666 } | 1734 } |
1667 Ice::Type SrcType = Src->getType(); | 1735 Ice::Type SrcType = Src->getType(); |
1668 if (!CastInst::castIsValid(LLVMCastOp, Context->convertToLLVMType(SrcType), | 1736 if (!CastInst::castIsValid(LLVMCastOp, Context->convertToLLVMType(SrcType), |
1669 Context->convertToLLVMType(CastType))) { | 1737 Context->convertToLLVMType(CastType))) { |
1670 std::string Buffer; | 1738 std::string Buffer; |
1671 raw_string_ostream StrBuf(Buffer); | 1739 raw_string_ostream StrBuf(Buffer); |
1672 StrBuf << "Illegal cast: " << Instruction::getOpcodeName(LLVMCastOp) | 1740 StrBuf << "Illegal cast: " << Instruction::getOpcodeName(LLVMCastOp) |
1673 << " " << SrcType << " to " << CastType; | 1741 << " " << SrcType << " to " << CastType; |
1674 Error(StrBuf.str()); | 1742 Error(StrBuf.str()); |
| 1743 appendErrorInstruction(CastType); |
1675 return; | 1744 return; |
1676 } | 1745 } |
1677 CurrentNode->appendInst( | 1746 CurrentNode->appendInst( |
1678 Ice::InstCast::create(Func, CastKind, getNextInstVar(CastType), Src)); | 1747 Ice::InstCast::create(Func, CastKind, getNextInstVar(CastType), Src)); |
1679 break; | 1748 return; |
1680 } | 1749 } |
1681 case naclbitc::FUNC_CODE_INST_VSELECT: { | 1750 case naclbitc::FUNC_CODE_INST_VSELECT: { |
1682 // VSELECT: [opval, opval, pred] | 1751 // VSELECT: [opval, opval, pred] |
1683 Ice::Operand *ThenVal = getRelativeOperand(Values[0], BaseIndex); | 1752 Ice::Operand *ThenVal = getRelativeOperand(Values[0], BaseIndex); |
1684 Ice::Type ThenType = ThenVal->getType(); | 1753 Ice::Type ThenType = ThenVal->getType(); |
1685 Ice::Operand *ElseVal = getRelativeOperand(Values[1], BaseIndex); | 1754 Ice::Operand *ElseVal = getRelativeOperand(Values[1], BaseIndex); |
1686 Ice::Type ElseType = ElseVal->getType(); | 1755 Ice::Type ElseType = ElseVal->getType(); |
1687 if (ThenType != ElseType) { | 1756 if (ThenType != ElseType) { |
1688 std::string Buffer; | 1757 std::string Buffer; |
1689 raw_string_ostream StrBuf(Buffer); | 1758 raw_string_ostream StrBuf(Buffer); |
1690 StrBuf << "Select operands not same type. Found " << ThenType << " and " | 1759 StrBuf << "Select operands not same type. Found " << ThenType << " and " |
1691 << ElseType; | 1760 << ElseType; |
1692 Error(StrBuf.str()); | 1761 Error(StrBuf.str()); |
| 1762 appendErrorInstruction(ThenType); |
1693 return; | 1763 return; |
1694 } | 1764 } |
1695 Ice::Operand *CondVal = getRelativeOperand(Values[2], BaseIndex); | 1765 Ice::Operand *CondVal = getRelativeOperand(Values[2], BaseIndex); |
1696 Ice::Type CondType = CondVal->getType(); | 1766 Ice::Type CondType = CondVal->getType(); |
1697 if (isVectorType(CondType)) { | 1767 if (isVectorType(CondType)) { |
1698 if (!isVectorType(ThenType) || | 1768 if (!isVectorType(ThenType) || |
1699 typeElementType(CondType) != Ice::IceType_i1 || | 1769 typeElementType(CondType) != Ice::IceType_i1 || |
1700 typeNumElements(ThenType) != typeNumElements(CondType)) { | 1770 typeNumElements(ThenType) != typeNumElements(CondType)) { |
1701 std::string Buffer; | 1771 std::string Buffer; |
1702 raw_string_ostream StrBuf(Buffer); | 1772 raw_string_ostream StrBuf(Buffer); |
1703 StrBuf << "Select condition type " << CondType | 1773 StrBuf << "Select condition type " << CondType |
1704 << " not allowed for values of type " << ThenType; | 1774 << " not allowed for values of type " << ThenType; |
1705 Error(StrBuf.str()); | 1775 Error(StrBuf.str()); |
| 1776 appendErrorInstruction(ThenType); |
1706 return; | 1777 return; |
1707 } | 1778 } |
1708 } else if (CondVal->getType() != Ice::IceType_i1) { | 1779 } else if (CondVal->getType() != Ice::IceType_i1) { |
1709 std::string Buffer; | 1780 std::string Buffer; |
1710 raw_string_ostream StrBuf(Buffer); | 1781 raw_string_ostream StrBuf(Buffer); |
1711 StrBuf << "Select condition " << CondVal << " not type i1. Found: " | 1782 StrBuf << "Select condition " << CondVal << " not type i1. Found: " |
1712 << CondVal->getType(); | 1783 << CondVal->getType(); |
1713 Error(StrBuf.str()); | 1784 Error(StrBuf.str()); |
| 1785 appendErrorInstruction(ThenType); |
1714 return; | 1786 return; |
1715 } | 1787 } |
1716 CurrentNode->appendInst(Ice::InstSelect::create( | 1788 CurrentNode->appendInst(Ice::InstSelect::create( |
1717 Func, getNextInstVar(ThenType), CondVal, ThenVal, ElseVal)); | 1789 Func, getNextInstVar(ThenType), CondVal, ThenVal, ElseVal)); |
1718 break; | 1790 return; |
1719 } | 1791 } |
1720 case naclbitc::FUNC_CODE_INST_EXTRACTELT: { | 1792 case naclbitc::FUNC_CODE_INST_EXTRACTELT: { |
1721 // EXTRACTELT: [opval, opval] | 1793 // EXTRACTELT: [opval, opval] |
1722 if (!isValidRecordSize(2, "function block extract element")) | 1794 if (!isValidRecordSize(2, "function block extract element")) |
1723 return; | 1795 return; |
1724 Ice::Operand *Vec = getRelativeOperand(Values[0], BaseIndex); | 1796 Ice::Operand *Vec = getRelativeOperand(Values[0], BaseIndex); |
1725 Ice::Type VecType = Vec->getType(); | 1797 Ice::Type VecType = Vec->getType(); |
1726 if (!Ice::isVectorType(VecType)) { | 1798 Ice::Operand *Index = getRelativeOperand(Values[1], BaseIndex); |
| 1799 VectorIndexCheckValue IndexCheckValue = validateVectorIndex(Vec, Index); |
| 1800 if (IndexCheckValue != VectorIndexValid) { |
1727 std::string Buffer; | 1801 std::string Buffer; |
1728 raw_string_ostream StrBuf(Buffer); | 1802 raw_string_ostream StrBuf(Buffer); |
1729 StrBuf << "Extractelement not on vector. Found: " << *Vec; | 1803 dumpVectorIndexCheckValue(StrBuf, IndexCheckValue); |
| 1804 StrBuf << ": extractelement " << VecType << " " << *Vec << ", " |
| 1805 << Index->getType() << " " << *Index; |
1730 Error(StrBuf.str()); | 1806 Error(StrBuf.str()); |
| 1807 appendErrorInstruction(VecType); |
| 1808 return; |
1731 } | 1809 } |
1732 Ice::Operand *Index = getRelativeOperand(Values[1], BaseIndex); | |
1733 if (Index->getType() != Ice::IceType_i32) { | |
1734 std::string Buffer; | |
1735 raw_string_ostream StrBuf(Buffer); | |
1736 StrBuf << "Extractelement index " << *Index << " not i32. Found: " | |
1737 << Index->getType(); | |
1738 Error(StrBuf.str()); | |
1739 } | |
1740 // TODO(kschimpf): Restrict index to a legal constant index (once | |
1741 // constants can be defined). | |
1742 CurrentNode->appendInst(Ice::InstExtractElement::create( | 1810 CurrentNode->appendInst(Ice::InstExtractElement::create( |
1743 Func, getNextInstVar(typeElementType(VecType)), Vec, Index)); | 1811 Func, getNextInstVar(typeElementType(VecType)), Vec, Index)); |
1744 break; | 1812 return; |
1745 } | 1813 } |
1746 case naclbitc::FUNC_CODE_INST_INSERTELT: { | 1814 case naclbitc::FUNC_CODE_INST_INSERTELT: { |
1747 // INSERTELT: [opval, opval, opval] | 1815 // INSERTELT: [opval, opval, opval] |
1748 if (!isValidRecordSize(3, "function block insert element")) | 1816 if (!isValidRecordSize(3, "function block insert element")) |
1749 return; | 1817 return; |
1750 Ice::Operand *Vec = getRelativeOperand(Values[0], BaseIndex); | 1818 Ice::Operand *Vec = getRelativeOperand(Values[0], BaseIndex); |
1751 Ice::Type VecType = Vec->getType(); | 1819 Ice::Type VecType = Vec->getType(); |
1752 if (!Ice::isVectorType(VecType)) { | 1820 Ice::Operand *Elt = getRelativeOperand(Values[1], BaseIndex); |
| 1821 Ice::Operand *Index = getRelativeOperand(Values[2], BaseIndex); |
| 1822 VectorIndexCheckValue IndexCheckValue = validateVectorIndex(Vec, Index); |
| 1823 if (IndexCheckValue != VectorIndexValid) { |
1753 std::string Buffer; | 1824 std::string Buffer; |
1754 raw_string_ostream StrBuf(Buffer); | 1825 raw_string_ostream StrBuf(Buffer); |
1755 StrBuf << "Insertelement not on vector. Found: " << *Vec; | 1826 dumpVectorIndexCheckValue(StrBuf, IndexCheckValue); |
| 1827 StrBuf << ": insertelement " << VecType << " " << *Vec << ", " |
| 1828 << Elt->getType() << " " << *Elt << ", " << Index->getType() << " " |
| 1829 << *Index; |
1756 Error(StrBuf.str()); | 1830 Error(StrBuf.str()); |
| 1831 appendErrorInstruction(Elt->getType()); |
| 1832 return; |
1757 } | 1833 } |
1758 Ice::Operand *Elt = getRelativeOperand(Values[1], BaseIndex); | |
1759 Ice::Type EltType = Elt->getType(); | |
1760 if (EltType != typeElementType(VecType)) { | |
1761 std::string Buffer; | |
1762 raw_string_ostream StrBuf(Buffer); | |
1763 StrBuf << "Insertelement element " << *Elt << " not type " | |
1764 << typeElementType(VecType) | |
1765 << ". Found: " << EltType; | |
1766 Error(StrBuf.str()); | |
1767 } | |
1768 Ice::Operand *Index = getRelativeOperand(Values[2], BaseIndex); | |
1769 if (Index->getType() != Ice::IceType_i32) { | |
1770 std::string Buffer; | |
1771 raw_string_ostream StrBuf(Buffer); | |
1772 StrBuf << "Insertelement index " << *Index << " not i32. Found: " | |
1773 << Index->getType(); | |
1774 Error(StrBuf.str()); | |
1775 } | |
1776 // TODO(kschimpf): Restrict index to a legal constant index (once | |
1777 // constants can be defined). | |
1778 CurrentNode->appendInst(Ice::InstInsertElement::create( | 1834 CurrentNode->appendInst(Ice::InstInsertElement::create( |
1779 Func, getNextInstVar(VecType), Vec, Elt, Index)); | 1835 Func, getNextInstVar(VecType), Vec, Elt, Index)); |
1780 break; | 1836 return; |
1781 } | 1837 } |
1782 case naclbitc::FUNC_CODE_INST_CMP2: { | 1838 case naclbitc::FUNC_CODE_INST_CMP2: { |
1783 // CMP2: [opval, opval, pred] | 1839 // CMP2: [opval, opval, pred] |
1784 if (!isValidRecordSize(3, "function block compare")) | 1840 if (!isValidRecordSize(3, "function block compare")) |
1785 return; | 1841 return; |
1786 Ice::Operand *Op1 = getRelativeOperand(Values[0], BaseIndex); | 1842 Ice::Operand *Op1 = getRelativeOperand(Values[0], BaseIndex); |
1787 Ice::Operand *Op2 = getRelativeOperand(Values[1], BaseIndex); | 1843 Ice::Operand *Op2 = getRelativeOperand(Values[1], BaseIndex); |
1788 Ice::Type Op1Type = Op1->getType(); | 1844 Ice::Type Op1Type = Op1->getType(); |
1789 Ice::Type Op2Type = Op2->getType(); | 1845 Ice::Type Op2Type = Op2->getType(); |
| 1846 Ice::Type DestType = getCompareResultType(Op1Type); |
1790 if (Op1Type != Op2Type) { | 1847 if (Op1Type != Op2Type) { |
1791 std::string Buffer; | 1848 std::string Buffer; |
1792 raw_string_ostream StrBuf(Buffer); | 1849 raw_string_ostream StrBuf(Buffer); |
1793 StrBuf << "Compare argument types differ: " << Op1Type | 1850 StrBuf << "Compare argument types differ: " << Op1Type |
1794 << " and " << Op2Type; | 1851 << " and " << Op2Type; |
1795 Error(StrBuf.str()); | 1852 Error(StrBuf.str()); |
1796 // TODO(kschimpf) Remove error recovery once implementation complete. | 1853 appendErrorInstruction(DestType); |
1797 Op2 = Op1; | 1854 Op2 = Op1; |
1798 } | 1855 } |
1799 Ice::Type DestType = getCompareResultType(Op1Type); | |
1800 if (DestType == Ice::IceType_void) { | 1856 if (DestType == Ice::IceType_void) { |
1801 std::string Buffer; | 1857 std::string Buffer; |
1802 raw_string_ostream StrBuf(Buffer); | 1858 raw_string_ostream StrBuf(Buffer); |
1803 StrBuf << "Compare not defined for type " << Op1Type; | 1859 StrBuf << "Compare not defined for type " << Op1Type; |
1804 Error(StrBuf.str()); | 1860 Error(StrBuf.str()); |
1805 return; | 1861 return; |
1806 } | 1862 } |
1807 Ice::Variable *Dest = getNextInstVar(DestType); | 1863 Ice::Variable *Dest = getNextInstVar(DestType); |
1808 if (isIntegerType(Op1Type)) { | 1864 if (isIntegerType(Op1Type)) { |
1809 Ice::InstIcmp::ICond Cond; | 1865 Ice::InstIcmp::ICond Cond; |
1810 if (!convertNaClBitcICmpOpToIce(Values[2], Cond)) { | 1866 if (!convertNaClBitcICmpOpToIce(Values[2], Cond)) { |
1811 std::string Buffer; | 1867 std::string Buffer; |
1812 raw_string_ostream StrBuf(Buffer); | 1868 raw_string_ostream StrBuf(Buffer); |
1813 StrBuf << "Compare record contains unknown integer predicate index: " | 1869 StrBuf << "Compare record contains unknown integer predicate index: " |
1814 << Values[2]; | 1870 << Values[2]; |
1815 Error(StrBuf.str()); | 1871 Error(StrBuf.str()); |
1816 // TODO(kschimpf) Remove error recovery once implementation complete. | 1872 appendErrorInstruction(DestType); |
1817 Cond = Ice::InstIcmp::Eq; | |
1818 } | 1873 } |
1819 CurrentNode->appendInst( | 1874 CurrentNode->appendInst( |
1820 Ice::InstIcmp::create(Func, Cond, Dest, Op1, Op2)); | 1875 Ice::InstIcmp::create(Func, Cond, Dest, Op1, Op2)); |
1821 } else if (isFloatingType(Op1Type)){ | 1876 } else if (isFloatingType(Op1Type)){ |
1822 Ice::InstFcmp::FCond Cond; | 1877 Ice::InstFcmp::FCond Cond; |
1823 if (!convertNaClBitcFCompOpToIce(Values[2], Cond)) { | 1878 if (!convertNaClBitcFCompOpToIce(Values[2], Cond)) { |
1824 std::string Buffer; | 1879 std::string Buffer; |
1825 raw_string_ostream StrBuf(Buffer); | 1880 raw_string_ostream StrBuf(Buffer); |
1826 StrBuf << "Compare record contains unknown float predicate index: " | 1881 StrBuf << "Compare record contains unknown float predicate index: " |
1827 << Values[2]; | 1882 << Values[2]; |
1828 Error(StrBuf.str()); | 1883 Error(StrBuf.str()); |
1829 // TODO(kschimpf) Remove error recovery once implementation complete. | 1884 appendErrorInstruction(DestType); |
1830 Cond = Ice::InstFcmp::False; | |
1831 } | 1885 } |
1832 CurrentNode->appendInst( | 1886 CurrentNode->appendInst( |
1833 Ice::InstFcmp::create(Func, Cond, Dest, Op1, Op2)); | 1887 Ice::InstFcmp::create(Func, Cond, Dest, Op1, Op2)); |
1834 } else { | 1888 } else { |
1835 // Not sure this can happen, but be safe. | 1889 // Not sure this can happen, but be safe. |
1836 std::string Buffer; | 1890 std::string Buffer; |
1837 raw_string_ostream StrBuf(Buffer); | 1891 raw_string_ostream StrBuf(Buffer); |
1838 StrBuf << "Compare on type not understood: " << Op1Type; | 1892 StrBuf << "Compare on type not understood: " << Op1Type; |
1839 Error(StrBuf.str()); | 1893 Error(StrBuf.str()); |
| 1894 appendErrorInstruction(DestType); |
1840 return; | 1895 return; |
1841 } | 1896 } |
1842 break; | 1897 return; |
1843 } | 1898 } |
1844 case naclbitc::FUNC_CODE_INST_RET: { | 1899 case naclbitc::FUNC_CODE_INST_RET: { |
1845 // RET: [opval?] | 1900 // RET: [opval?] |
1846 if (!isValidRecordSizeInRange(0, 1, "function block ret")) | 1901 if (!isValidRecordSizeInRange(0, 1, "function block ret")) |
1847 return; | 1902 return; |
1848 if (Values.size() == 0) { | 1903 if (Values.size() == 0) { |
1849 CurrentNode->appendInst(Ice::InstRet::create(Func)); | 1904 CurrentNode->appendInst(Ice::InstRet::create(Func)); |
1850 } else { | 1905 } else { |
1851 CurrentNode->appendInst( | 1906 CurrentNode->appendInst( |
1852 Ice::InstRet::create(Func, getRelativeOperand(Values[0], BaseIndex))); | 1907 Ice::InstRet::create(Func, getRelativeOperand(Values[0], BaseIndex))); |
1853 } | 1908 } |
1854 InstIsTerminating = true; | 1909 InstIsTerminating = true; |
1855 break; | 1910 return; |
1856 } | 1911 } |
1857 case naclbitc::FUNC_CODE_INST_BR: { | 1912 case naclbitc::FUNC_CODE_INST_BR: { |
1858 if (Values.size() == 1) { | 1913 if (Values.size() == 1) { |
1859 // BR: [bb#] | 1914 // BR: [bb#] |
1860 Ice::CfgNode *Block = getBranchBasicBlock(Values[0]); | 1915 Ice::CfgNode *Block = getBranchBasicBlock(Values[0]); |
1861 if (Block == nullptr) | 1916 if (Block == nullptr) |
1862 return; | 1917 return; |
1863 CurrentNode->appendInst(Ice::InstBr::create(Func, Block)); | 1918 CurrentNode->appendInst(Ice::InstBr::create(Func, Block)); |
1864 } else { | 1919 } else { |
1865 // BR: [bb#, bb#, opval] | 1920 // BR: [bb#, bb#, opval] |
1866 if (!isValidRecordSize(3, "function block branch")) | 1921 if (!isValidRecordSize(3, "function block branch")) |
1867 return; | 1922 return; |
1868 Ice::Operand *Cond = getRelativeOperand(Values[2], BaseIndex); | 1923 Ice::Operand *Cond = getRelativeOperand(Values[2], BaseIndex); |
1869 if (Cond->getType() != Ice::IceType_i1) { | 1924 if (Cond->getType() != Ice::IceType_i1) { |
1870 std::string Buffer; | 1925 std::string Buffer; |
1871 raw_string_ostream StrBuf(Buffer); | 1926 raw_string_ostream StrBuf(Buffer); |
1872 StrBuf << "Branch condition " << *Cond << " not i1. Found: " | 1927 StrBuf << "Branch condition " << *Cond << " not i1. Found: " |
1873 << Cond->getType(); | 1928 << Cond->getType(); |
1874 Error(StrBuf.str()); | 1929 Error(StrBuf.str()); |
1875 return; | 1930 return; |
1876 } | 1931 } |
1877 Ice::CfgNode *ThenBlock = getBranchBasicBlock(Values[0]); | 1932 Ice::CfgNode *ThenBlock = getBranchBasicBlock(Values[0]); |
1878 Ice::CfgNode *ElseBlock = getBranchBasicBlock(Values[1]); | 1933 Ice::CfgNode *ElseBlock = getBranchBasicBlock(Values[1]); |
1879 if (ThenBlock == nullptr || ElseBlock == nullptr) | 1934 if (ThenBlock == nullptr || ElseBlock == nullptr) |
1880 return; | 1935 return; |
1881 CurrentNode->appendInst( | 1936 CurrentNode->appendInst( |
1882 Ice::InstBr::create(Func, Cond, ThenBlock, ElseBlock)); | 1937 Ice::InstBr::create(Func, Cond, ThenBlock, ElseBlock)); |
1883 } | 1938 } |
1884 InstIsTerminating = true; | 1939 InstIsTerminating = true; |
1885 break; | 1940 return; |
1886 } | 1941 } |
1887 case naclbitc::FUNC_CODE_INST_SWITCH: { | 1942 case naclbitc::FUNC_CODE_INST_SWITCH: { |
1888 // SWITCH: [Condty, Cond, BbIndex, NumCases Case ...] | 1943 // SWITCH: [Condty, Cond, BbIndex, NumCases Case ...] |
1889 // where Case = [1, 1, Value, BbIndex]. | 1944 // where Case = [1, 1, Value, BbIndex]. |
1890 // | 1945 // |
1891 // Note: Unlike most instructions, we don't infer the type of | 1946 // Note: Unlike most instructions, we don't infer the type of |
1892 // Cond, but provide it as a separate field. There are also | 1947 // Cond, but provide it as a separate field. There are also |
1893 // unnecesary data fields (i.e. constants 1). These were not | 1948 // unnecesary data fields (i.e. constants 1). These were not |
1894 // cleaned up in PNaCl bitcode because the bitcode format was | 1949 // cleaned up in PNaCl bitcode because the bitcode format was |
1895 // already frozen when the problem was noticed. | 1950 // already frozen when the problem was noticed. |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1933 return; | 1988 return; |
1934 } | 1989 } |
1935 APInt Value(BitWidth, | 1990 APInt Value(BitWidth, |
1936 NaClDecodeSignRotatedValue(Values[ValCaseIndex + 2]), | 1991 NaClDecodeSignRotatedValue(Values[ValCaseIndex + 2]), |
1937 true); | 1992 true); |
1938 Ice::CfgNode *Label = getBranchBasicBlock(Values[ValCaseIndex + 3]); | 1993 Ice::CfgNode *Label = getBranchBasicBlock(Values[ValCaseIndex + 3]); |
1939 Switch->addBranch(CaseIndex, Value.getSExtValue(), Label); | 1994 Switch->addBranch(CaseIndex, Value.getSExtValue(), Label); |
1940 } | 1995 } |
1941 CurrentNode->appendInst(Switch); | 1996 CurrentNode->appendInst(Switch); |
1942 InstIsTerminating = true; | 1997 InstIsTerminating = true; |
1943 break; | 1998 return; |
1944 } | 1999 } |
1945 case naclbitc::FUNC_CODE_INST_UNREACHABLE: { | 2000 case naclbitc::FUNC_CODE_INST_UNREACHABLE: { |
1946 // UNREACHABLE: [] | 2001 // UNREACHABLE: [] |
1947 if (!isValidRecordSize(0, "function block unreachable")) | 2002 if (!isValidRecordSize(0, "function block unreachable")) |
1948 return; | 2003 return; |
1949 CurrentNode->appendInst( | 2004 CurrentNode->appendInst( |
1950 Ice::InstUnreachable::create(Func)); | 2005 Ice::InstUnreachable::create(Func)); |
1951 InstIsTerminating = true; | 2006 InstIsTerminating = true; |
1952 break; | 2007 return; |
1953 } | 2008 } |
1954 case naclbitc::FUNC_CODE_INST_PHI: { | 2009 case naclbitc::FUNC_CODE_INST_PHI: { |
1955 // PHI: [ty, val1, bb1, ..., valN, bbN] for n >= 2. | 2010 // PHI: [ty, val1, bb1, ..., valN, bbN] for n >= 2. |
1956 if (!isValidRecordSizeAtLeast(3, "function block phi")) | 2011 if (!isValidRecordSizeAtLeast(3, "function block phi")) |
1957 return; | 2012 return; |
| 2013 Ice::Type Ty = Context->getSimpleTypeByID(Values[0]); |
1958 if ((Values.size() & 0x1) == 0) { | 2014 if ((Values.size() & 0x1) == 0) { |
1959 // Not an odd number of values. | 2015 // Not an odd number of values. |
1960 std::string Buffer; | 2016 std::string Buffer; |
1961 raw_string_ostream StrBuf(Buffer); | 2017 raw_string_ostream StrBuf(Buffer); |
1962 StrBuf << "function block phi record size not valid: " << Values.size(); | 2018 StrBuf << "function block phi record size not valid: " << Values.size(); |
1963 Error(StrBuf.str()); | 2019 Error(StrBuf.str()); |
| 2020 appendErrorInstruction(Ty); |
1964 return; | 2021 return; |
1965 } | 2022 } |
1966 Ice::Type Ty = Context->getSimpleTypeByID(Values[0]); | |
1967 if (Ty == Ice::IceType_void) { | 2023 if (Ty == Ice::IceType_void) { |
1968 Error("Phi record using type void not allowed"); | 2024 Error("Phi record using type void not allowed"); |
1969 return; | 2025 return; |
1970 } | 2026 } |
1971 Ice::Variable *Dest = getNextInstVar(Ty); | 2027 Ice::Variable *Dest = getNextInstVar(Ty); |
1972 Ice::InstPhi *Phi = Ice::InstPhi::create(Func, Values.size() >> 1, Dest); | 2028 Ice::InstPhi *Phi = Ice::InstPhi::create(Func, Values.size() >> 1, Dest); |
1973 for (unsigned i = 1; i < Values.size(); i += 2) { | 2029 for (unsigned i = 1; i < Values.size(); i += 2) { |
1974 Ice::Operand *Op = | 2030 Ice::Operand *Op = |
1975 getRelativeOperand(NaClDecodeSignRotatedValue(Values[i]), BaseIndex); | 2031 getRelativeOperand(NaClDecodeSignRotatedValue(Values[i]), BaseIndex); |
1976 if (Op->getType() != Ty) { | 2032 if (Op->getType() != Ty) { |
1977 std::string Buffer; | 2033 std::string Buffer; |
1978 raw_string_ostream StrBuf(Buffer); | 2034 raw_string_ostream StrBuf(Buffer); |
1979 StrBuf << "Value " << *Op << " not type " << Ty | 2035 StrBuf << "Value " << *Op << " not type " << Ty |
1980 << " in phi instruction. Found: " << Op->getType(); | 2036 << " in phi instruction. Found: " << Op->getType(); |
1981 Error(StrBuf.str()); | 2037 Error(StrBuf.str()); |
| 2038 appendErrorInstruction(Ty); |
1982 return; | 2039 return; |
1983 } | 2040 } |
1984 Phi->addArgument(Op, getBasicBlock(Values[i + 1])); | 2041 Phi->addArgument(Op, getBasicBlock(Values[i + 1])); |
1985 } | 2042 } |
1986 CurrentNode->appendInst(Phi); | 2043 CurrentNode->appendInst(Phi); |
1987 break; | 2044 return; |
1988 } | 2045 } |
1989 case naclbitc::FUNC_CODE_INST_ALLOCA: { | 2046 case naclbitc::FUNC_CODE_INST_ALLOCA: { |
1990 // ALLOCA: [Size, align] | 2047 // ALLOCA: [Size, align] |
1991 if (!isValidRecordSize(2, "function block alloca")) | 2048 if (!isValidRecordSize(2, "function block alloca")) |
1992 return; | 2049 return; |
1993 Ice::Operand *ByteCount = getRelativeOperand(Values[0], BaseIndex); | 2050 Ice::Operand *ByteCount = getRelativeOperand(Values[0], BaseIndex); |
| 2051 Ice::Type PtrTy = Context->getIcePointerType(); |
1994 if (ByteCount->getType() != Ice::IceType_i32) { | 2052 if (ByteCount->getType() != Ice::IceType_i32) { |
1995 std::string Buffer; | 2053 std::string Buffer; |
1996 raw_string_ostream StrBuf(Buffer); | 2054 raw_string_ostream StrBuf(Buffer); |
1997 StrBuf << "Alloca on non-i32 value. Found: " << *ByteCount; | 2055 StrBuf << "Alloca on non-i32 value. Found: " << *ByteCount; |
1998 Error(StrBuf.str()); | 2056 Error(StrBuf.str()); |
| 2057 appendErrorInstruction(PtrTy); |
1999 return; | 2058 return; |
2000 } | 2059 } |
2001 unsigned Alignment; | 2060 unsigned Alignment; |
2002 extractAlignment("Alloca", Values[1], Alignment); | 2061 extractAlignment("Alloca", Values[1], Alignment); |
2003 CurrentNode->appendInst( | 2062 CurrentNode->appendInst(Ice::InstAlloca::create(Func, ByteCount, Alignment, |
2004 Ice::InstAlloca::create(Func, ByteCount, Alignment, | 2063 getNextInstVar(PtrTy))); |
2005 getNextInstVar(Context->getIcePointerType()))); | 2064 return; |
2006 break; | |
2007 } | 2065 } |
2008 case naclbitc::FUNC_CODE_INST_LOAD: { | 2066 case naclbitc::FUNC_CODE_INST_LOAD: { |
2009 // LOAD: [address, align, ty] | 2067 // LOAD: [address, align, ty] |
2010 if (!isValidRecordSize(3, "function block load")) | 2068 if (!isValidRecordSize(3, "function block load")) |
2011 return; | 2069 return; |
2012 Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex); | 2070 Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex); |
2013 if (!isValidPointerType(Address, "Load")) | 2071 Ice::Type Ty = Context->getSimpleTypeByID(Values[2]); |
| 2072 if (!isValidPointerType(Address, "Load")) { |
| 2073 appendErrorInstruction(Ty); |
2014 return; | 2074 return; |
| 2075 } |
2015 unsigned Alignment; | 2076 unsigned Alignment; |
2016 extractAlignment("Load", Values[1], Alignment); | 2077 extractAlignment("Load", Values[1], Alignment); |
2017 Ice::Type Ty = Context->getSimpleTypeByID(Values[2]); | 2078 if (!isValidLoadStoreAlignment(Alignment, Ty, "Load")) { |
2018 if (!isValidLoadStoreAlignment(Alignment, Ty, "Load")) | 2079 appendErrorInstruction(Ty); |
2019 return; | 2080 return; |
| 2081 } |
2020 CurrentNode->appendInst( | 2082 CurrentNode->appendInst( |
2021 Ice::InstLoad::create(Func, getNextInstVar(Ty), Address, Alignment)); | 2083 Ice::InstLoad::create(Func, getNextInstVar(Ty), Address, Alignment)); |
2022 break; | 2084 return; |
2023 } | 2085 } |
2024 case naclbitc::FUNC_CODE_INST_STORE: { | 2086 case naclbitc::FUNC_CODE_INST_STORE: { |
2025 // STORE: [address, value, align] | 2087 // STORE: [address, value, align] |
2026 if (!isValidRecordSize(3, "function block store")) | 2088 if (!isValidRecordSize(3, "function block store")) |
2027 return; | 2089 return; |
2028 Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex); | 2090 Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex); |
2029 if (!isValidPointerType(Address, "Store")) | 2091 if (!isValidPointerType(Address, "Store")) |
2030 return; | 2092 return; |
2031 Ice::Operand *Value = getRelativeOperand(Values[1], BaseIndex); | 2093 Ice::Operand *Value = getRelativeOperand(Values[1], BaseIndex); |
2032 unsigned Alignment; | 2094 unsigned Alignment; |
2033 extractAlignment("Store", Values[2], Alignment); | 2095 extractAlignment("Store", Values[2], Alignment); |
2034 if (!isValidLoadStoreAlignment(Alignment, Value->getType(), "Store")) | 2096 if (!isValidLoadStoreAlignment(Alignment, Value->getType(), "Store")) |
2035 return; | 2097 return; |
2036 CurrentNode->appendInst( | 2098 CurrentNode->appendInst( |
2037 Ice::InstStore::create(Func, Value, Address, Alignment)); | 2099 Ice::InstStore::create(Func, Value, Address, Alignment)); |
2038 break; | 2100 return; |
2039 } | 2101 } |
2040 case naclbitc::FUNC_CODE_INST_CALL: | 2102 case naclbitc::FUNC_CODE_INST_CALL: |
2041 case naclbitc::FUNC_CODE_INST_CALL_INDIRECT: { | 2103 case naclbitc::FUNC_CODE_INST_CALL_INDIRECT: { |
2042 // CALL: [cc, fnid, arg0, arg1...] | 2104 // CALL: [cc, fnid, arg0, arg1...] |
2043 // CALL_INDIRECT: [cc, fn, returnty, args...] | 2105 // CALL_INDIRECT: [cc, fn, returnty, args...] |
2044 // | 2106 // |
2045 // Note: The difference between CALL and CALL_INDIRECT is that | 2107 // Note: The difference between CALL and CALL_INDIRECT is that |
2046 // CALL has a reference to an explicit function declaration, while | 2108 // CALL has a reference to an explicit function declaration, while |
2047 // the CALL_INDIRECT is just an address. For CALL, we can infer | 2109 // the CALL_INDIRECT is just an address. For CALL, we can infer |
2048 // the return type by looking up the type signature associated | 2110 // the return type by looking up the type signature associated |
2049 // with the function declaration. For CALL_INDIRECT we can only | 2111 // with the function declaration. For CALL_INDIRECT we can only |
2050 // infer the type signature via argument types, and the | 2112 // infer the type signature via argument types, and the |
2051 // corresponding return type stored in CALL_INDIRECT record. | 2113 // corresponding return type stored in CALL_INDIRECT record. |
2052 Ice::SizeT ParamsStartIndex = 2; | 2114 Ice::SizeT ParamsStartIndex = 2; |
2053 if (Record.GetCode() == naclbitc::FUNC_CODE_INST_CALL) { | 2115 if (Record.GetCode() == naclbitc::FUNC_CODE_INST_CALL) { |
2054 if (!isValidRecordSizeAtLeast(2, "function block call")) | 2116 if (!isValidRecordSizeAtLeast(2, "function block call")) |
2055 return; | 2117 return; |
2056 } else { | 2118 } else { |
2057 if (!isValidRecordSizeAtLeast(3, "function block call indirect")) | 2119 if (!isValidRecordSizeAtLeast(3, "function block call indirect")) |
2058 return; | 2120 return; |
2059 ParamsStartIndex = 3; | 2121 ParamsStartIndex = 3; |
2060 } | 2122 } |
2061 | 2123 |
2062 // Extract call information. | |
2063 uint64_t CCInfo = Values[0]; | |
2064 CallingConv::ID CallingConv; | |
2065 if (!naclbitc::DecodeCallingConv(CCInfo >> 1, CallingConv)) { | |
2066 std::string Buffer; | |
2067 raw_string_ostream StrBuf(Buffer); | |
2068 StrBuf << "Function call calling convention value " << (CCInfo >> 1) | |
2069 << " not understood."; | |
2070 Error(StrBuf.str()); | |
2071 return; | |
2072 } | |
2073 bool IsTailCall = static_cast<bool>(CCInfo & 1); | |
2074 | |
2075 // Extract out the called function and its return type. | 2124 // Extract out the called function and its return type. |
2076 uint32_t CalleeIndex = convertRelativeToAbsIndex(Values[1], BaseIndex); | 2125 uint32_t CalleeIndex = convertRelativeToAbsIndex(Values[1], BaseIndex); |
2077 Ice::Operand *Callee = getOperand(CalleeIndex); | 2126 Ice::Operand *Callee = getOperand(CalleeIndex); |
2078 Ice::Type ReturnType = Ice::IceType_void; | 2127 Ice::Type ReturnType = Ice::IceType_void; |
2079 const Ice::Intrinsics::FullIntrinsicInfo *IntrinsicInfo = nullptr; | 2128 const Ice::Intrinsics::FullIntrinsicInfo *IntrinsicInfo = nullptr; |
2080 if (Record.GetCode() == naclbitc::FUNC_CODE_INST_CALL) { | 2129 if (Record.GetCode() == naclbitc::FUNC_CODE_INST_CALL) { |
2081 Ice::FunctionDeclaration *Fcn = Context->getFunctionByID(CalleeIndex); | 2130 Ice::FunctionDeclaration *Fcn = Context->getFunctionByID(CalleeIndex); |
2082 const Ice::FuncSigType &Signature = Fcn->getSignature(); | 2131 const Ice::FuncSigType &Signature = Fcn->getSignature(); |
2083 ReturnType = Signature.getReturnType(); | 2132 ReturnType = Signature.getReturnType(); |
2084 | 2133 |
2085 // Check if this direct call is to an Intrinsic (starts with "llvm.") | 2134 // Check if this direct call is to an Intrinsic (starts with "llvm.") |
2086 static Ice::IceString LLVMPrefix("llvm."); | 2135 static Ice::IceString LLVMPrefix("llvm."); |
2087 Ice::IceString Name = Fcn->getName(); | 2136 Ice::IceString Name = Fcn->getName(); |
2088 if (isStringPrefix(Name, LLVMPrefix)) { | 2137 if (isStringPrefix(Name, LLVMPrefix)) { |
2089 Ice::IceString Suffix = Name.substr(LLVMPrefix.size()); | 2138 Ice::IceString Suffix = Name.substr(LLVMPrefix.size()); |
2090 IntrinsicInfo = | 2139 IntrinsicInfo = |
2091 getTranslator().getContext()->getIntrinsicsInfo().find(Suffix); | 2140 getTranslator().getContext()->getIntrinsicsInfo().find(Suffix); |
2092 if (!IntrinsicInfo) { | 2141 if (!IntrinsicInfo) { |
2093 std::string Buffer; | 2142 std::string Buffer; |
2094 raw_string_ostream StrBuf(Buffer); | 2143 raw_string_ostream StrBuf(Buffer); |
2095 StrBuf << "Invalid PNaCl intrinsic call to " << Name; | 2144 StrBuf << "Invalid PNaCl intrinsic call to " << Name; |
2096 Error(StrBuf.str()); | 2145 Error(StrBuf.str()); |
| 2146 appendErrorInstruction(ReturnType); |
2097 return; | 2147 return; |
2098 } | 2148 } |
2099 } | 2149 } |
2100 } else { | 2150 } else { |
2101 ReturnType = Context->getSimpleTypeByID(Values[2]); | 2151 ReturnType = Context->getSimpleTypeByID(Values[2]); |
2102 } | 2152 } |
2103 | 2153 |
| 2154 // Extract call information. |
| 2155 uint64_t CCInfo = Values[0]; |
| 2156 CallingConv::ID CallingConv; |
| 2157 if (!naclbitc::DecodeCallingConv(CCInfo >> 1, CallingConv)) { |
| 2158 std::string Buffer; |
| 2159 raw_string_ostream StrBuf(Buffer); |
| 2160 StrBuf << "Function call calling convention value " << (CCInfo >> 1) |
| 2161 << " not understood."; |
| 2162 Error(StrBuf.str()); |
| 2163 appendErrorInstruction(ReturnType); |
| 2164 return; |
| 2165 } |
| 2166 bool IsTailCall = static_cast<bool>(CCInfo & 1); |
| 2167 |
2104 // Create the call instruction. | 2168 // Create the call instruction. |
2105 Ice::Variable *Dest = (ReturnType == Ice::IceType_void) | 2169 Ice::Variable *Dest = (ReturnType == Ice::IceType_void) |
2106 ? nullptr | 2170 ? nullptr |
2107 : getNextInstVar(ReturnType); | 2171 : getNextInstVar(ReturnType); |
2108 Ice::SizeT NumParams = Values.size() - ParamsStartIndex; | 2172 Ice::SizeT NumParams = Values.size() - ParamsStartIndex; |
2109 Ice::InstCall *Inst = nullptr; | 2173 Ice::InstCall *Inst = nullptr; |
2110 if (IntrinsicInfo) { | 2174 if (IntrinsicInfo) { |
2111 Inst = | 2175 Inst = |
2112 Ice::InstIntrinsicCall::create(Func, NumParams, Dest, Callee, | 2176 Ice::InstIntrinsicCall::create(Func, NumParams, Dest, Callee, |
2113 IntrinsicInfo->Info); | 2177 IntrinsicInfo->Info); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2164 } | 2228 } |
2165 | 2229 |
2166 CurrentNode->appendInst(Inst); | 2230 CurrentNode->appendInst(Inst); |
2167 return; | 2231 return; |
2168 } | 2232 } |
2169 case naclbitc::FUNC_CODE_INST_FORWARDTYPEREF: { | 2233 case naclbitc::FUNC_CODE_INST_FORWARDTYPEREF: { |
2170 // FORWARDTYPEREF: [opval, ty] | 2234 // FORWARDTYPEREF: [opval, ty] |
2171 if (!isValidRecordSize(2, "function block forward type ref")) | 2235 if (!isValidRecordSize(2, "function block forward type ref")) |
2172 return; | 2236 return; |
2173 setOperand(Values[0], createInstVar(Context->getSimpleTypeByID(Values[1]))); | 2237 setOperand(Values[0], createInstVar(Context->getSimpleTypeByID(Values[1]))); |
2174 break; | 2238 return; |
2175 } | 2239 } |
2176 default: | 2240 default: |
2177 // Generate error message! | 2241 // Generate error message! |
2178 BlockParserBaseClass::ProcessRecord(); | 2242 BlockParserBaseClass::ProcessRecord(); |
2179 break; | 2243 return; |
2180 } | 2244 } |
2181 } | 2245 } |
2182 | 2246 |
2183 /// Parses constants within a function block. | 2247 /// Parses constants within a function block. |
2184 class ConstantsParser : public BlockParserBaseClass { | 2248 class ConstantsParser : public BlockParserBaseClass { |
2185 ConstantsParser(const ConstantsParser &) = delete; | 2249 ConstantsParser(const ConstantsParser &) = delete; |
2186 ConstantsParser &operator=(const ConstantsParser &) = delete; | 2250 ConstantsParser &operator=(const ConstantsParser &) = delete; |
2187 | 2251 |
2188 public: | 2252 public: |
2189 ConstantsParser(unsigned BlockID, FunctionParser *FuncParser) | 2253 ConstantsParser(unsigned BlockID, FunctionParser *FuncParser) |
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2599 | 2663 |
2600 if (TopLevelBlocks != 1) { | 2664 if (TopLevelBlocks != 1) { |
2601 errs() << IRFilename | 2665 errs() << IRFilename |
2602 << ": Contains more than one module. Found: " << TopLevelBlocks | 2666 << ": Contains more than one module. Found: " << TopLevelBlocks |
2603 << "\n"; | 2667 << "\n"; |
2604 ErrorStatus = true; | 2668 ErrorStatus = true; |
2605 } | 2669 } |
2606 } | 2670 } |
2607 | 2671 |
2608 } // end of namespace Ice | 2672 } // end of namespace Ice |
OLD | NEW |