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 1586 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1597 return isValidIntegerLogicalOp(Op, Ty); | 1597 return isValidIntegerLogicalOp(Op, Ty); |
| 1598 case naclbitc::BINOP_OR: | 1598 case naclbitc::BINOP_OR: |
| 1599 Op = Ice::InstArithmetic::Or; | 1599 Op = Ice::InstArithmetic::Or; |
| 1600 return isValidIntegerLogicalOp(Op, Ty); | 1600 return isValidIntegerLogicalOp(Op, Ty); |
| 1601 case naclbitc::BINOP_XOR: | 1601 case naclbitc::BINOP_XOR: |
| 1602 Op = Ice::InstArithmetic::Xor; | 1602 Op = Ice::InstArithmetic::Xor; |
| 1603 return isValidIntegerLogicalOp(Op, Ty); | 1603 return isValidIntegerLogicalOp(Op, Ty); |
| 1604 } | 1604 } |
| 1605 } | 1605 } |
| 1606 | 1606 |
| 1607 /// Converts an LLVM cast opcode LLVMCastOp to the corresponding Ice | 1607 /// Simplifies out vector types from Type1 and Type2, if both are vectors |
| 1608 /// cast opcode and assigns to CastKind. Returns true if successful, | 1608 /// of the same size. |
| 1609 /// false otherwise. | 1609 void simplifyOutCommonVectorType(Ice::Type &Type1, Ice::Type &Type2) const { |
|
Jim Stichnoth
2014/12/12 22:47:54
All of these new functions, up to and including is
Karl
2014/12/15 17:40:18
Done.
| |
| 1610 bool convertLLVMCastOpToIceOp(Instruction::CastOps LLVMCastOp, | 1610 bool IsType1Vector = isVectorType(Type1); |
| 1611 Ice::InstCast::OpKind &CastKind) const { | 1611 bool IsType2Vector = isVectorType(Type2); |
| 1612 switch (LLVMCastOp) { | 1612 if (IsType1Vector != IsType2Vector) |
| 1613 case Instruction::ZExt: | 1613 return; |
| 1614 CastKind = Ice::InstCast::Zext; | 1614 if (IsType1Vector) { |
| 1615 break; | 1615 if (typeNumElements(Type1) != typeNumElements(Type2)) |
| 1616 case Instruction::SExt: | 1616 return; |
| 1617 CastKind = Ice::InstCast::Sext; | 1617 Type1 = typeElementType(Type1); |
| 1618 break; | 1618 Type2 = typeElementType(Type2); |
| 1619 case Instruction::Trunc: | 1619 } |
| 1620 CastKind = Ice::InstCast::Trunc; | 1620 } |
| 1621 break; | 1621 |
| 1622 case Instruction::FPTrunc: | 1622 /// Returns true iff an integer truncation from SourceType to TargetType is |
| 1623 CastKind = Ice::InstCast::Fptrunc; | 1623 /// valid. |
| 1624 break; | 1624 bool isIntTruncCastValid(Ice::Type SourceType, Ice::Type TargetType) const { |
| 1625 case Instruction::FPExt: | 1625 if (!(Ice::isIntegerType(SourceType) && Ice::isIntegerType(TargetType))) |
| 1626 CastKind = Ice::InstCast::Fpext; | |
| 1627 break; | |
| 1628 case Instruction::FPToSI: | |
| 1629 CastKind = Ice::InstCast::Fptosi; | |
| 1630 break; | |
| 1631 case Instruction::FPToUI: | |
| 1632 CastKind = Ice::InstCast::Fptoui; | |
| 1633 break; | |
| 1634 case Instruction::SIToFP: | |
| 1635 CastKind = Ice::InstCast::Sitofp; | |
| 1636 break; | |
| 1637 case Instruction::UIToFP: | |
| 1638 CastKind = Ice::InstCast::Uitofp; | |
| 1639 break; | |
| 1640 case Instruction::BitCast: | |
| 1641 CastKind = Ice::InstCast::Bitcast; | |
| 1642 break; | |
| 1643 default: | |
| 1644 return false; | 1626 return false; |
| 1627 simplifyOutCommonVectorType(SourceType, TargetType); | |
| 1628 return Ice::getScalarIntBitWidth(SourceType) > | |
|
jvoung (off chromium)
2014/12/12 23:46:45
nit: One of the getScalarIntBitWidth is prefixed w
Karl
2014/12/15 17:40:18
Good point. When I factored this out, I forgot to
| |
| 1629 getScalarIntBitWidth(TargetType); | |
| 1630 } | |
| 1631 | |
| 1632 /// Returns true iff a floating type truncation form SoruceType to TargetType | |
|
Jim Stichnoth
2014/12/12 22:47:54
SourceType
Karl
2014/12/15 17:40:18
Done.
Also fixed "form" -> "from".
| |
| 1633 /// is valid. | |
| 1634 bool isFloatTruncCastValid(Ice::Type SourceType, Ice::Type TargetType) const { | |
| 1635 if (!(Ice::isFloatingType(SourceType) && Ice::isFloatingType(TargetType))) | |
| 1636 return false; | |
| 1637 simplifyOutCommonVectorType(SourceType, TargetType); | |
| 1638 return SourceType == Ice::IceType_f64 and TargetType == Ice::IceType_f32; | |
|
Jim Stichnoth
2014/12/12 22:47:54
"and"? wow.
Karl
2014/12/15 17:40:18
Done.
| |
| 1639 } | |
| 1640 | |
| 1641 /// Returns true iff an integer extension from SourceType to TargetType is | |
| 1642 /// valid. | |
| 1643 bool isIntExtCastValid(Ice::Type SourceType, Ice::Type TargetType) const { | |
| 1644 return isIntTruncCastValid(TargetType, SourceType); | |
| 1645 } | |
| 1646 | |
| 1647 /// Returns true iff a floating type extension form SourceType to TargetType | |
|
Jim Stichnoth
2014/12/12 22:47:54
from
Karl
2014/12/15 17:40:18
Done.
| |
| 1648 /// is valid. | |
| 1649 bool isFloatExtCastValid(Ice::Type SourceType, Ice::Type TargetType) const { | |
| 1650 return isFloatTruncCastValid(TargetType, SourceType); | |
| 1651 } | |
| 1652 | |
| 1653 /// Returns true if a floating type SourceType to integer type TargetType | |
|
Jim Stichnoth
2014/12/12 22:47:54
Use "iff" for consistency?
Also, I think the word
Karl
2014/12/15 17:40:18
Done and Done.
| |
| 1654 /// is valid. | |
| 1655 bool isFPToICastValid(Ice::Type SourceType, Ice::Type TargetType) const { | |
|
Jim Stichnoth
2014/12/12 22:47:54
name it isFloatToIntCastValid for consistency?
Karl
2014/12/15 17:40:18
Done.
| |
| 1656 if (!(Ice::isFloatingType(SourceType) && Ice::isIntegerType(TargetType))) | |
| 1657 return false; | |
| 1658 bool IsSourceVector = isVectorType(SourceType); | |
| 1659 bool IsTargetVector = isVectorType(TargetType); | |
| 1660 if (IsSourceVector != IsTargetVector) | |
| 1661 return false; | |
| 1662 if (IsSourceVector) { | |
| 1663 if (typeNumElements(SourceType) != typeNumElements(TargetType)) | |
|
Jim Stichnoth
2014/12/12 22:47:54
Might be better to just use:
return typeNumEleme
Karl
2014/12/15 17:40:18
Done.
| |
| 1664 return false; | |
| 1645 } | 1665 } |
| 1646 return true; | 1666 return true; |
| 1647 } | 1667 } |
| 1648 | 1668 |
| 1669 /// Returns true iff an integer type SourceType to floating type TargetType | |
|
Jim Stichnoth
2014/12/12 22:47:55
add "cast" to the comment?
Karl
2014/12/15 17:40:18
Done.
| |
| 1670 /// is valid. | |
| 1671 bool isIToFPCastValid(Ice::Type SourceType, Ice::Type TargetType) const { | |
|
Jim Stichnoth
2014/12/12 22:47:55
suggest isIntToFloatCastValid
Karl
2014/12/15 17:40:18
Done.
| |
| 1672 return isFPToICastValid(TargetType, SourceType); | |
| 1673 } | |
| 1674 | |
| 1675 /// Returns the number of bits used to model type Ty when defining the | |
| 1676 /// bitcast instruction. | |
| 1677 Ice::SizeT bitcastSizeInBits(Ice::Type Ty) const { | |
| 1678 if (Ice::isVectorType(Ty)) | |
| 1679 return Ice::typeNumElements(Ty) * | |
| 1680 bitcastSizeInBits(Ice::typeElementType(Ty)); | |
| 1681 if (Ty == Ice::IceType_i1) | |
| 1682 return 1; | |
| 1683 return Ice::typeWidthInBytes(Ty) * CHAR_BIT; | |
| 1684 } | |
| 1685 | |
| 1686 /// Returns true if a bitcast from SourceType to TargetType is allowed. | |
| 1687 bool isBitcastCastValid(Ice::Type SourceType, Ice::Type TargetType) const { | |
|
Jim Stichnoth
2014/12/12 22:47:54
maybe just call it isBitcastValid()?
Karl
2014/12/15 17:40:18
Done.
| |
| 1688 return bitcastSizeInBits(SourceType) == bitcastSizeInBits(TargetType); | |
| 1689 } | |
| 1690 | |
| 1691 /// Returns true if the NaCl bitcode Opcode is a valid cast opcode | |
| 1692 /// for converting SourceType to TargetType. Updates CastKind to the | |
| 1693 /// corresponding instruction cast opcode. Also generates error message | |
|
Jim Stichnoth
2014/12/12 22:47:54
generates *an* error message
Karl
2014/12/15 17:40:19
Done.
| |
| 1694 /// if function returns false. | |
|
Jim Stichnoth
2014/12/12 22:47:55
what function?
Karl
2014/12/15 17:40:18
Added "this" and replaced "if" with "when".
| |
| 1695 bool convertCastOpToIceOp(uint64_t Opcode, Ice::Type SourceType, | |
| 1696 Ice::Type TargetType, | |
| 1697 Ice::InstCast::OpKind &CastKind) { | |
| 1698 bool Result; | |
| 1699 switch (Opcode) { | |
| 1700 default: { | |
| 1701 std::string Buffer; | |
| 1702 raw_string_ostream StrBuf(Buffer); | |
| 1703 StrBuf << "Cast opcode " << Opcode << " not understood.\n"; | |
| 1704 Error(StrBuf.str()); | |
| 1705 // TODO(kschimpf) Remove error recovery once implementation complete. | |
| 1706 CastKind = Ice::InstCast::Bitcast; | |
| 1707 return false; | |
| 1708 } | |
| 1709 case naclbitc::CAST_TRUNC: | |
| 1710 CastKind = Ice::InstCast::Trunc; | |
| 1711 Result = isIntTruncCastValid(SourceType, TargetType); | |
| 1712 break; | |
| 1713 case naclbitc::CAST_ZEXT: | |
| 1714 CastKind = Ice::InstCast::Zext; | |
| 1715 Result = isIntExtCastValid(SourceType, TargetType); | |
| 1716 break; | |
| 1717 case naclbitc::CAST_SEXT: | |
| 1718 CastKind = Ice::InstCast::Sext; | |
| 1719 Result = isIntExtCastValid(SourceType, TargetType); | |
| 1720 break; | |
| 1721 case naclbitc::CAST_FPTOUI: | |
| 1722 CastKind = Ice::InstCast::Fptoui; | |
| 1723 Result = isFPToICastValid(SourceType, TargetType); | |
| 1724 break; | |
| 1725 case naclbitc::CAST_FPTOSI: | |
| 1726 CastKind = Ice::InstCast::Fptosi; | |
| 1727 Result = isFPToICastValid(SourceType, TargetType); | |
| 1728 break; | |
| 1729 case naclbitc::CAST_UITOFP: | |
| 1730 CastKind = Ice::InstCast::Uitofp; | |
| 1731 Result = isIToFPCastValid(SourceType, TargetType); | |
| 1732 break; | |
| 1733 case naclbitc::CAST_SITOFP: | |
| 1734 CastKind = Ice::InstCast::Sitofp; | |
| 1735 Result = isIToFPCastValid(SourceType, TargetType); | |
| 1736 break; | |
| 1737 case naclbitc::CAST_FPTRUNC: | |
| 1738 CastKind = Ice::InstCast::Fptrunc; | |
| 1739 Result = isFloatTruncCastValid(SourceType, TargetType); | |
| 1740 break; | |
| 1741 case naclbitc::CAST_FPEXT: | |
| 1742 CastKind = Ice::InstCast::Fpext; | |
| 1743 Result = isFloatExtCastValid(SourceType, TargetType); | |
| 1744 break; | |
| 1745 case naclbitc::CAST_BITCAST: | |
| 1746 CastKind = Ice::InstCast::Bitcast; | |
| 1747 Result = isBitcastCastValid(SourceType, TargetType); | |
| 1748 break; | |
| 1749 } | |
| 1750 if (!Result) { | |
| 1751 std::string Buffer; | |
| 1752 raw_string_ostream StrBuf(Buffer); | |
| 1753 StrBuf << "Illegal cast: " << Ice::InstCast::getCastName(CastKind) << " " | |
| 1754 << SourceType << " to " << TargetType; | |
| 1755 Error(StrBuf.str()); | |
| 1756 } | |
| 1757 return Result; | |
| 1758 } | |
| 1759 | |
| 1649 // Converts PNaCl bitcode Icmp operator to corresponding ICE op. | 1760 // Converts PNaCl bitcode Icmp operator to corresponding ICE op. |
| 1650 // Returns true if able to convert, false otherwise. | 1761 // Returns true if able to convert, false otherwise. |
| 1651 bool convertNaClBitcICmpOpToIce(uint64_t Op, | 1762 bool convertNaClBitcICmpOpToIce(uint64_t Op, |
| 1652 Ice::InstIcmp::ICond &Cond) const { | 1763 Ice::InstIcmp::ICond &Cond) const { |
| 1653 switch (Op) { | 1764 switch (Op) { |
| 1654 case naclbitc::ICMP_EQ: | 1765 case naclbitc::ICMP_EQ: |
| 1655 Cond = Ice::InstIcmp::Eq; | 1766 Cond = Ice::InstIcmp::Eq; |
| 1656 return true; | 1767 return true; |
| 1657 case naclbitc::ICMP_NE: | 1768 case naclbitc::ICMP_NE: |
| 1658 Cond = Ice::InstIcmp::Ne; | 1769 Cond = Ice::InstIcmp::Ne; |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1869 CurrentNode->appendInst(Ice::InstArithmetic::create( | 1980 CurrentNode->appendInst(Ice::InstArithmetic::create( |
| 1870 Func, Opcode, getNextInstVar(Type1), Op1, Op2)); | 1981 Func, Opcode, getNextInstVar(Type1), Op1, Op2)); |
| 1871 return; | 1982 return; |
| 1872 } | 1983 } |
| 1873 case naclbitc::FUNC_CODE_INST_CAST: { | 1984 case naclbitc::FUNC_CODE_INST_CAST: { |
| 1874 // CAST: [opval, destty, castopc] | 1985 // CAST: [opval, destty, castopc] |
| 1875 if (!isValidRecordSize(3, "cast")) | 1986 if (!isValidRecordSize(3, "cast")) |
| 1876 return; | 1987 return; |
| 1877 Ice::Operand *Src = getRelativeOperand(Values[0], BaseIndex); | 1988 Ice::Operand *Src = getRelativeOperand(Values[0], BaseIndex); |
| 1878 Ice::Type CastType = Context->getSimpleTypeByID(Values[1]); | 1989 Ice::Type CastType = Context->getSimpleTypeByID(Values[1]); |
| 1879 Instruction::CastOps LLVMCastOp; | |
| 1880 Ice::InstCast::OpKind CastKind; | 1990 Ice::InstCast::OpKind CastKind; |
| 1881 if (!naclbitc::DecodeCastOpcode(Values[2], LLVMCastOp) || | |
| 1882 !convertLLVMCastOpToIceOp(LLVMCastOp, CastKind)) { | |
| 1883 std::string Buffer; | |
| 1884 raw_string_ostream StrBuf(Buffer); | |
| 1885 StrBuf << "Cast opcode not understood: " << Values[2]; | |
| 1886 Error(StrBuf.str()); | |
| 1887 appendErrorInstruction(CastType); | |
| 1888 return; | |
| 1889 } | |
| 1890 if (isIRGenerationDisabled()) { | 1991 if (isIRGenerationDisabled()) { |
| 1891 assert(Src == nullptr); | 1992 assert(Src == nullptr); |
| 1892 setNextLocalInstIndex(nullptr); | 1993 setNextLocalInstIndex(nullptr); |
| 1893 return; | 1994 return; |
| 1894 } | 1995 } |
| 1895 Ice::Type SrcType = Src->getType(); | 1996 if (!convertCastOpToIceOp(Values[2], Src->getType(), CastType, CastKind)) { |
| 1896 if (!CastInst::castIsValid(LLVMCastOp, Context->convertToLLVMType(SrcType), | |
| 1897 Context->convertToLLVMType(CastType))) { | |
| 1898 std::string Buffer; | |
| 1899 raw_string_ostream StrBuf(Buffer); | |
| 1900 StrBuf << "Illegal cast: " << Instruction::getOpcodeName(LLVMCastOp) | |
| 1901 << " " << SrcType << " to " << CastType; | |
| 1902 Error(StrBuf.str()); | |
| 1903 appendErrorInstruction(CastType); | 1997 appendErrorInstruction(CastType); |
| 1904 return; | 1998 return; |
| 1905 } | 1999 } |
| 1906 CurrentNode->appendInst( | 2000 CurrentNode->appendInst( |
| 1907 Ice::InstCast::create(Func, CastKind, getNextInstVar(CastType), Src)); | 2001 Ice::InstCast::create(Func, CastKind, getNextInstVar(CastType), Src)); |
| 1908 return; | 2002 return; |
| 1909 } | 2003 } |
| 1910 case naclbitc::FUNC_CODE_INST_VSELECT: { | 2004 case naclbitc::FUNC_CODE_INST_VSELECT: { |
| 1911 // VSELECT: [opval, opval, pred] | 2005 // VSELECT: [opval, opval, pred] |
| 1912 if (!isValidRecordSize(3, "select")) | 2006 if (!isValidRecordSize(3, "select")) |
| (...skipping 1025 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2938 | 3032 |
| 2939 if (TopLevelBlocks != 1) { | 3033 if (TopLevelBlocks != 1) { |
| 2940 errs() << IRFilename | 3034 errs() << IRFilename |
| 2941 << ": Contains more than one module. Found: " << TopLevelBlocks | 3035 << ": Contains more than one module. Found: " << TopLevelBlocks |
| 2942 << "\n"; | 3036 << "\n"; |
| 2943 ErrorStatus = true; | 3037 ErrorStatus = true; |
| 2944 } | 3038 } |
| 2945 } | 3039 } |
| 2946 | 3040 |
| 2947 } // end of namespace Ice | 3041 } // end of namespace Ice |
| OLD | NEW |