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 |