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