| 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 1492 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1503 const auto *C = dyn_cast<Ice::ConstantInteger32>(Index); | 1503 const auto *C = dyn_cast<Ice::ConstantInteger32>(Index); |
| 1504 if (C == nullptr) | 1504 if (C == nullptr) |
| 1505 return VectorIndexNotConstant; | 1505 return VectorIndexNotConstant; |
| 1506 if (static_cast<size_t>(C->getValue()) >= typeNumElements(VecType)) | 1506 if (static_cast<size_t>(C->getValue()) >= typeNumElements(VecType)) |
| 1507 return VectorIndexNotInRange; | 1507 return VectorIndexNotInRange; |
| 1508 if (Index->getType() != Ice::IceType_i32) | 1508 if (Index->getType() != Ice::IceType_i32) |
| 1509 return VectorIndexNotI32; | 1509 return VectorIndexNotI32; |
| 1510 return VectorIndexValid; | 1510 return VectorIndexValid; |
| 1511 } | 1511 } |
| 1512 | 1512 |
| 1513 // Reports that the given binary Opcode, for the given type Ty, | |
| 1514 // is not understood. | |
| 1515 void ReportInvalidBinopOpcode(unsigned Opcode, Ice::Type Ty); | |
| 1516 | |
| 1517 // Returns true if the Str begins with Prefix. | 1513 // Returns true if the Str begins with Prefix. |
| 1518 bool isStringPrefix(Ice::IceString &Str, Ice::IceString &Prefix) { | 1514 bool isStringPrefix(Ice::IceString &Str, Ice::IceString &Prefix) { |
| 1519 const size_t PrefixSize = Prefix.size(); | 1515 const size_t PrefixSize = Prefix.size(); |
| 1520 if (Str.size() < PrefixSize) | 1516 if (Str.size() < PrefixSize) |
| 1521 return false; | 1517 return false; |
| 1522 for (size_t i = 0; i < PrefixSize; ++i) { | 1518 for (size_t i = 0; i < PrefixSize; ++i) { |
| 1523 if (Str[i] != Prefix[i]) | 1519 if (Str[i] != Prefix[i]) |
| 1524 return false; | 1520 return false; |
| 1525 } | 1521 } |
| 1526 return true; | 1522 return true; |
| 1527 } | 1523 } |
| 1528 | 1524 |
| 1529 // Takes the PNaCl bitcode binary operator Opcode, and the opcode | 1525 // Takes the PNaCl bitcode binary operator Opcode, and the opcode |
| 1530 // type Ty, and sets Op to the corresponding ICE binary | 1526 // type Ty, and sets Op to the corresponding ICE binary |
| 1531 // opcode. Returns true if able to convert, false otherwise. | 1527 // opcode. Returns true if able to convert, false otherwise. |
| 1532 bool convertBinopOpcode(unsigned Opcode, Ice::Type Ty, | 1528 bool convertBinopOpcode(unsigned Opcode, Ice::Type Ty, |
| 1533 Ice::InstArithmetic::OpKind &Op) { | 1529 Ice::InstArithmetic::OpKind &Op) { |
| 1534 Instruction::BinaryOps LLVMOpcode; | 1530 switch (Opcode) { |
| 1535 if (!naclbitc::DecodeBinaryOpcode(Opcode, Context->convertToLLVMType(Ty), | 1531 default: { |
| 1536 LLVMOpcode)) { | 1532 std::string Buffer; |
| 1537 ReportInvalidBinopOpcode(Opcode, Ty); | 1533 raw_string_ostream StrBuf(Buffer); |
| 1534 StrBuf << "Binary opcode " << Opcode << "not understood for type " << Ty; |
| 1535 Error(StrBuf.str()); |
| 1538 // TODO(kschimpf) Remove error recovery once implementation complete. | 1536 // TODO(kschimpf) Remove error recovery once implementation complete. |
| 1539 Op = Ice::InstArithmetic::Add; | 1537 Op = Ice::InstArithmetic::Add; |
| 1540 return false; | 1538 return false; |
| 1541 } | 1539 } |
| 1542 switch (LLVMOpcode) { | 1540 case naclbitc::BINOP_ADD: |
| 1543 default: { | 1541 if (Ice::isIntegerType(Ty)) { |
| 1544 ReportInvalidBinopOpcode(Opcode, Ty); | 1542 Op = Ice::InstArithmetic::Add; |
| 1545 // TODO(kschimpf) Remove error recovery once implementation complete. | 1543 return isValidIntegerArithOp(Op, Ty); |
| 1546 Op = Ice::InstArithmetic::Add; | 1544 } else { |
| 1547 return false; | 1545 Op = Ice::InstArithmetic::Fadd; |
| 1548 } | 1546 return isValidFloatingArithOp(Op, Ty); |
| 1549 case Instruction::Add: | 1547 } |
| 1550 Op = Ice::InstArithmetic::Add; | 1548 case naclbitc::BINOP_SUB: |
| 1551 return isValidIntegerArithOp(Op, Ty); | 1549 if (Ice::isIntegerType(Ty)) { |
| 1552 case Instruction::FAdd: | 1550 Op = Ice::InstArithmetic::Sub; |
| 1553 Op = Ice::InstArithmetic::Fadd; | 1551 return isValidIntegerArithOp(Op, Ty); |
| 1554 return isValidFloatingArithOp(Op, Ty); | 1552 } else { |
| 1555 case Instruction::Sub: | 1553 Op = Ice::InstArithmetic::Fsub; |
| 1556 Op = Ice::InstArithmetic::Sub; | 1554 return isValidFloatingArithOp(Op, Ty); |
| 1557 return isValidIntegerArithOp(Op, Ty); | 1555 } |
| 1558 case Instruction::FSub: | 1556 case naclbitc::BINOP_MUL: |
| 1559 Op = Ice::InstArithmetic::Fsub; | 1557 if (Ice::isIntegerType(Ty)) { |
| 1560 return isValidFloatingArithOp(Op, Ty); | 1558 Op = Ice::InstArithmetic::Mul; |
| 1561 case Instruction::Mul: | 1559 return isValidIntegerArithOp(Op, Ty); |
| 1562 Op = Ice::InstArithmetic::Mul; | 1560 } else { |
| 1563 return isValidIntegerArithOp(Op, Ty); | 1561 Op = Ice::InstArithmetic::Fmul; |
| 1564 case Instruction::FMul: | 1562 return isValidFloatingArithOp(Op, Ty); |
| 1565 Op = Ice::InstArithmetic::Fmul; | 1563 } |
| 1566 return isValidFloatingArithOp(Op, Ty); | 1564 case naclbitc::BINOP_UDIV: |
| 1567 case Instruction::UDiv: | |
| 1568 Op = Ice::InstArithmetic::Udiv; | 1565 Op = Ice::InstArithmetic::Udiv; |
| 1569 return isValidIntegerArithOp(Op, Ty); | 1566 return isValidIntegerArithOp(Op, Ty); |
| 1570 case Instruction::SDiv: | 1567 case naclbitc::BINOP_SDIV: |
| 1571 Op = Ice::InstArithmetic::Sdiv; | 1568 if (Ice::isIntegerType(Ty)) { |
| 1572 return isValidIntegerArithOp(Op, Ty); | 1569 Op = Ice::InstArithmetic::Sdiv; |
| 1573 case Instruction::FDiv: | 1570 return isValidIntegerArithOp(Op, Ty); |
| 1574 Op = Ice::InstArithmetic::Fdiv; | 1571 } else { |
| 1575 return isValidFloatingArithOp(Op, Ty); | 1572 Op = Ice::InstArithmetic::Fdiv; |
| 1576 case Instruction::URem: | 1573 return isValidFloatingArithOp(Op, Ty); |
| 1574 } |
| 1575 case naclbitc::BINOP_UREM: |
| 1577 Op = Ice::InstArithmetic::Urem; | 1576 Op = Ice::InstArithmetic::Urem; |
| 1578 return isValidIntegerArithOp(Op, Ty); | 1577 return isValidIntegerArithOp(Op, Ty); |
| 1579 case Instruction::SRem: | 1578 case naclbitc::BINOP_SREM: |
| 1580 Op = Ice::InstArithmetic::Srem; | 1579 if (Ice::isIntegerType(Ty)) { |
| 1581 return isValidIntegerArithOp(Op, Ty); | 1580 Op = Ice::InstArithmetic::Srem; |
| 1582 case Instruction::FRem: | 1581 return isValidIntegerArithOp(Op, Ty); |
| 1583 Op = Ice::InstArithmetic::Frem; | 1582 } else { |
| 1584 return isValidFloatingArithOp(Op, Ty); | 1583 Op = Ice::InstArithmetic::Frem; |
| 1585 case Instruction::Shl: | 1584 return isValidFloatingArithOp(Op, Ty); |
| 1585 } |
| 1586 case naclbitc::BINOP_SHL: |
| 1586 Op = Ice::InstArithmetic::Shl; | 1587 Op = Ice::InstArithmetic::Shl; |
| 1587 return isValidIntegerArithOp(Op, Ty); | 1588 return isValidIntegerArithOp(Op, Ty); |
| 1588 case Instruction::LShr: | 1589 case naclbitc::BINOP_LSHR: |
| 1589 Op = Ice::InstArithmetic::Lshr; | 1590 Op = Ice::InstArithmetic::Lshr; |
| 1590 return isValidIntegerArithOp(Op, Ty); | 1591 return isValidIntegerArithOp(Op, Ty); |
| 1591 case Instruction::AShr: | 1592 case naclbitc::BINOP_ASHR: |
| 1592 Op = Ice::InstArithmetic::Ashr; | 1593 Op = Ice::InstArithmetic::Ashr; |
| 1593 return isValidIntegerArithOp(Op, Ty); | 1594 return isValidIntegerArithOp(Op, Ty); |
| 1594 case Instruction::And: | 1595 case naclbitc::BINOP_AND: |
| 1595 Op = Ice::InstArithmetic::And; | 1596 Op = Ice::InstArithmetic::And; |
| 1596 return isValidIntegerLogicalOp(Op, Ty); | 1597 return isValidIntegerLogicalOp(Op, Ty); |
| 1597 case Instruction::Or: | 1598 case naclbitc::BINOP_OR: |
| 1598 Op = Ice::InstArithmetic::Or; | 1599 Op = Ice::InstArithmetic::Or; |
| 1599 return isValidIntegerLogicalOp(Op, Ty); | 1600 return isValidIntegerLogicalOp(Op, Ty); |
| 1600 case Instruction::Xor: | 1601 case naclbitc::BINOP_XOR: |
| 1601 Op = Ice::InstArithmetic::Xor; | 1602 Op = Ice::InstArithmetic::Xor; |
| 1602 return isValidIntegerLogicalOp(Op, Ty); | 1603 return isValidIntegerLogicalOp(Op, Ty); |
| 1603 } | 1604 } |
| 1604 } | 1605 } |
| 1605 | 1606 |
| 1606 /// Converts an LLVM cast opcode LLVMCastOp to the corresponding Ice | 1607 /// Converts an LLVM cast opcode LLVMCastOp to the corresponding Ice |
| 1607 /// cast opcode and assigns to CastKind. Returns true if successful, | 1608 /// cast opcode and assigns to CastKind. Returns true if successful, |
| 1608 /// false otherwise. | 1609 /// false otherwise. |
| 1609 bool convertLLVMCastOpToIceOp(Instruction::CastOps LLVMCastOp, | 1610 bool convertLLVMCastOpToIceOp(Instruction::CastOps LLVMCastOp, |
| 1610 Ice::InstCast::OpKind &CastKind) const { | 1611 Ice::InstCast::OpKind &CastKind) const { |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1757 void appendErrorInstruction(Ice::Type Ty) { | 1758 void appendErrorInstruction(Ice::Type Ty) { |
| 1758 // Note: we don't worry about downstream translation errors because | 1759 // Note: we don't worry about downstream translation errors because |
| 1759 // the function will not be translated if any errors occur. | 1760 // the function will not be translated if any errors occur. |
| 1760 if (Ty == Ice::IceType_void) | 1761 if (Ty == Ice::IceType_void) |
| 1761 return; | 1762 return; |
| 1762 Ice::Variable *Var = getNextInstVar(Ty); | 1763 Ice::Variable *Var = getNextInstVar(Ty); |
| 1763 CurrentNode->appendInst(Ice::InstAssign::create(Func, Var, Var)); | 1764 CurrentNode->appendInst(Ice::InstAssign::create(Func, Var, Var)); |
| 1764 } | 1765 } |
| 1765 }; | 1766 }; |
| 1766 | 1767 |
| 1767 void FunctionParser::ReportInvalidBinopOpcode(unsigned Opcode, Ice::Type Ty) { | |
| 1768 std::string Buffer; | |
| 1769 raw_string_ostream StrBuf(Buffer); | |
| 1770 StrBuf << "Binary opcode " << Opcode << "not understood for type " << Ty; | |
| 1771 Error(StrBuf.str()); | |
| 1772 } | |
| 1773 | |
| 1774 void FunctionParser::ExitBlock() { | 1768 void FunctionParser::ExitBlock() { |
| 1775 if (isIRGenerationDisabled()) { | 1769 if (isIRGenerationDisabled()) { |
| 1776 popTimerIfTimingEachFunction(); | 1770 popTimerIfTimingEachFunction(); |
| 1777 return; | 1771 return; |
| 1778 } | 1772 } |
| 1779 // Before translating, check for blocks without instructions, and | 1773 // Before translating, check for blocks without instructions, and |
| 1780 // insert unreachable. This shouldn't happen, but be safe. | 1774 // insert unreachable. This shouldn't happen, but be safe. |
| 1781 unsigned Index = 0; | 1775 unsigned Index = 0; |
| 1782 for (Ice::CfgNode *Node : Func->getNodes()) { | 1776 for (Ice::CfgNode *Node : Func->getNodes()) { |
| 1783 if (Node->getInsts().empty()) { | 1777 if (Node->getInsts().empty()) { |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1861 if (Type1 != Type2) { | 1855 if (Type1 != Type2) { |
| 1862 std::string Buffer; | 1856 std::string Buffer; |
| 1863 raw_string_ostream StrBuf(Buffer); | 1857 raw_string_ostream StrBuf(Buffer); |
| 1864 StrBuf << "Binop argument types differ: " << Type1 << " and " << Type2; | 1858 StrBuf << "Binop argument types differ: " << Type1 << " and " << Type2; |
| 1865 Error(StrBuf.str()); | 1859 Error(StrBuf.str()); |
| 1866 appendErrorInstruction(Type1); | 1860 appendErrorInstruction(Type1); |
| 1867 return; | 1861 return; |
| 1868 } | 1862 } |
| 1869 | 1863 |
| 1870 Ice::InstArithmetic::OpKind Opcode; | 1864 Ice::InstArithmetic::OpKind Opcode; |
| 1871 if (!convertBinopOpcode(Values[2], Type1, Opcode)) | 1865 if (!convertBinopOpcode(Values[2], Type1, Opcode)) { |
| 1866 appendErrorInstruction(Type1); |
| 1872 return; | 1867 return; |
| 1868 } |
| 1873 CurrentNode->appendInst(Ice::InstArithmetic::create( | 1869 CurrentNode->appendInst(Ice::InstArithmetic::create( |
| 1874 Func, Opcode, getNextInstVar(Type1), Op1, Op2)); | 1870 Func, Opcode, getNextInstVar(Type1), Op1, Op2)); |
| 1875 return; | 1871 return; |
| 1876 } | 1872 } |
| 1877 case naclbitc::FUNC_CODE_INST_CAST: { | 1873 case naclbitc::FUNC_CODE_INST_CAST: { |
| 1878 // CAST: [opval, destty, castopc] | 1874 // CAST: [opval, destty, castopc] |
| 1879 if (!isValidRecordSize(3, "cast")) | 1875 if (!isValidRecordSize(3, "cast")) |
| 1880 return; | 1876 return; |
| 1881 Ice::Operand *Src = getRelativeOperand(Values[0], BaseIndex); | 1877 Ice::Operand *Src = getRelativeOperand(Values[0], BaseIndex); |
| 1882 Ice::Type CastType = Context->getSimpleTypeByID(Values[1]); | 1878 Ice::Type CastType = Context->getSimpleTypeByID(Values[1]); |
| (...skipping 1059 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2942 | 2938 |
| 2943 if (TopLevelBlocks != 1) { | 2939 if (TopLevelBlocks != 1) { |
| 2944 errs() << IRFilename | 2940 errs() << IRFilename |
| 2945 << ": Contains more than one module. Found: " << TopLevelBlocks | 2941 << ": Contains more than one module. Found: " << TopLevelBlocks |
| 2946 << "\n"; | 2942 << "\n"; |
| 2947 ErrorStatus = true; | 2943 ErrorStatus = true; |
| 2948 } | 2944 } |
| 2949 } | 2945 } |
| 2950 | 2946 |
| 2951 } // end of namespace Ice | 2947 } // end of namespace Ice |
| OLD | NEW |