| 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 992 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1003 // Checks if the type of operand Op is the valid pointer type, for | 1003 // Checks if the type of operand Op is the valid pointer type, for |
| 1004 // the given InstructionName. Returns true if valid. Otherwise | 1004 // the given InstructionName. Returns true if valid. Otherwise |
| 1005 // generates an error message and returns false. | 1005 // generates an error message and returns false. |
| 1006 bool isValidPointerType(Ice::Operand *Op, const char *InstructionName) { | 1006 bool isValidPointerType(Ice::Operand *Op, const char *InstructionName) { |
| 1007 Ice::Type PtrType = Context->getIcePointerType(); | 1007 Ice::Type PtrType = Context->getIcePointerType(); |
| 1008 if (Op->getType() == PtrType) | 1008 if (Op->getType() == PtrType) |
| 1009 return true; | 1009 return true; |
| 1010 std::string Buffer; | 1010 std::string Buffer; |
| 1011 raw_string_ostream StrBuf(Buffer); | 1011 raw_string_ostream StrBuf(Buffer); |
| 1012 StrBuf << InstructionName << " address not " << PtrType | 1012 StrBuf << InstructionName << " address not " << PtrType |
| 1013 << ". Found: " << Op; | 1013 << ". Found: " << *Op; |
| 1014 Error(StrBuf.str()); | 1014 Error(StrBuf.str()); |
| 1015 return false; | 1015 return false; |
| 1016 } | 1016 } |
| 1017 | 1017 |
| 1018 // Checks if loading/storing a value of type Ty is allowed. | 1018 // Checks if loading/storing a value of type Ty is allowed. |
| 1019 // Returns true if Valid. Otherwise generates an error message and | 1019 // Returns true if Valid. Otherwise generates an error message and |
| 1020 // returns false. | 1020 // returns false. |
| 1021 bool isValidLoadStoreType(Ice::Type Ty, const char *InstructionName) { | 1021 bool isValidLoadStoreType(Ice::Type Ty, const char *InstructionName) { |
| 1022 if (isLoadStoreType(Ty)) | 1022 if (isLoadStoreType(Ty)) |
| 1023 return true; | 1023 return true; |
| (...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1416 return; | 1416 return; |
| 1417 } | 1417 } |
| 1418 Ice::Operand *CondVal = getRelativeOperand(Values[2], BaseIndex); | 1418 Ice::Operand *CondVal = getRelativeOperand(Values[2], BaseIndex); |
| 1419 Ice::Type CondType = CondVal->getType(); | 1419 Ice::Type CondType = CondVal->getType(); |
| 1420 if (isVectorType(CondType)) { | 1420 if (isVectorType(CondType)) { |
| 1421 if (!isVectorType(ThenType) || | 1421 if (!isVectorType(ThenType) || |
| 1422 typeElementType(CondType) != Ice::IceType_i1 || | 1422 typeElementType(CondType) != Ice::IceType_i1 || |
| 1423 typeNumElements(ThenType) != typeNumElements(CondType)) { | 1423 typeNumElements(ThenType) != typeNumElements(CondType)) { |
| 1424 std::string Buffer; | 1424 std::string Buffer; |
| 1425 raw_string_ostream StrBuf(Buffer); | 1425 raw_string_ostream StrBuf(Buffer); |
| 1426 StrBuf << "Select condition " << CondType | 1426 StrBuf << "Select condition type " << CondType |
| 1427 << " not allowed for values of type " << ThenType; | 1427 << " not allowed for values of type " << ThenType; |
| 1428 Error(StrBuf.str()); | 1428 Error(StrBuf.str()); |
| 1429 return; | 1429 return; |
| 1430 } | 1430 } |
| 1431 } else if (CondVal->getType() != Ice::IceType_i1) { | 1431 } else if (CondVal->getType() != Ice::IceType_i1) { |
| 1432 std::string Buffer; | 1432 std::string Buffer; |
| 1433 raw_string_ostream StrBuf(Buffer); | 1433 raw_string_ostream StrBuf(Buffer); |
| 1434 StrBuf << "Select condition not type i1. Found: " << CondVal->getType(); | 1434 StrBuf << "Select condition " << CondVal << " not type i1. Found: " |
| 1435 << CondVal->getType(); |
| 1435 Error(StrBuf.str()); | 1436 Error(StrBuf.str()); |
| 1436 return; | 1437 return; |
| 1437 } | 1438 } |
| 1438 CurrentNode->appendInst(Ice::InstSelect::create( | 1439 CurrentNode->appendInst(Ice::InstSelect::create( |
| 1439 Func, getNextInstVar(ThenType), CondVal, ThenVal, ElseVal)); | 1440 Func, getNextInstVar(ThenType), CondVal, ThenVal, ElseVal)); |
| 1440 break; | 1441 break; |
| 1441 } | 1442 } |
| 1442 case naclbitc::FUNC_CODE_INST_EXTRACTELT: { | 1443 case naclbitc::FUNC_CODE_INST_EXTRACTELT: { |
| 1443 // EXTRACTELT: [opval, opval] | 1444 // EXTRACTELT: [opval, opval] |
| 1444 if (!isValidRecordSize(2, "function block extract element")) | 1445 if (!isValidRecordSize(2, "function block extract element")) |
| 1445 return; | 1446 return; |
| 1446 Ice::Operand *Vec = getRelativeOperand(Values[0], BaseIndex); | 1447 Ice::Operand *Vec = getRelativeOperand(Values[0], BaseIndex); |
| 1447 Ice::Type VecType = Vec->getType(); | 1448 Ice::Type VecType = Vec->getType(); |
| 1448 if (!Ice::isVectorType(VecType)) { | 1449 if (!Ice::isVectorType(VecType)) { |
| 1449 std::string Buffer; | 1450 std::string Buffer; |
| 1450 raw_string_ostream StrBuf(Buffer); | 1451 raw_string_ostream StrBuf(Buffer); |
| 1451 StrBuf << "Extractelement not on vector. Found: " << Vec; | 1452 StrBuf << "Extractelement not on vector. Found: " << *Vec; |
| 1452 Error(StrBuf.str()); | 1453 Error(StrBuf.str()); |
| 1453 } | 1454 } |
| 1454 Ice::Operand *Index = getRelativeOperand(Values[1], BaseIndex); | 1455 Ice::Operand *Index = getRelativeOperand(Values[1], BaseIndex); |
| 1455 if (Index->getType() != Ice::IceType_i32) { | 1456 if (Index->getType() != Ice::IceType_i32) { |
| 1456 std::string Buffer; | 1457 std::string Buffer; |
| 1457 raw_string_ostream StrBuf(Buffer); | 1458 raw_string_ostream StrBuf(Buffer); |
| 1458 StrBuf << "Extractelement index not i32. Found: " << Index; | 1459 StrBuf << "Extractelement index " << *Index << " not i32. Found: " |
| 1460 << Index->getType(); |
| 1459 Error(StrBuf.str()); | 1461 Error(StrBuf.str()); |
| 1460 } | 1462 } |
| 1461 // TODO(kschimpf): Restrict index to a legal constant index (once | 1463 // TODO(kschimpf): Restrict index to a legal constant index (once |
| 1462 // constants can be defined). | 1464 // constants can be defined). |
| 1463 CurrentNode->appendInst(Ice::InstExtractElement::create( | 1465 CurrentNode->appendInst(Ice::InstExtractElement::create( |
| 1464 Func, getNextInstVar(typeElementType(VecType)), Vec, Index)); | 1466 Func, getNextInstVar(typeElementType(VecType)), Vec, Index)); |
| 1465 break; | 1467 break; |
| 1466 } | 1468 } |
| 1467 case naclbitc::FUNC_CODE_INST_INSERTELT: { | 1469 case naclbitc::FUNC_CODE_INST_INSERTELT: { |
| 1468 // INSERTELT: [opval, opval, opval] | 1470 // INSERTELT: [opval, opval, opval] |
| 1469 if (!isValidRecordSize(3, "function block insert element")) | 1471 if (!isValidRecordSize(3, "function block insert element")) |
| 1470 return; | 1472 return; |
| 1471 Ice::Operand *Vec = getRelativeOperand(Values[0], BaseIndex); | 1473 Ice::Operand *Vec = getRelativeOperand(Values[0], BaseIndex); |
| 1472 Ice::Type VecType = Vec->getType(); | 1474 Ice::Type VecType = Vec->getType(); |
| 1473 if (!Ice::isVectorType(VecType)) { | 1475 if (!Ice::isVectorType(VecType)) { |
| 1474 std::string Buffer; | 1476 std::string Buffer; |
| 1475 raw_string_ostream StrBuf(Buffer); | 1477 raw_string_ostream StrBuf(Buffer); |
| 1476 StrBuf << "Insertelement not on vector. Found: " << Vec; | 1478 StrBuf << "Insertelement not on vector. Found: " << *Vec; |
| 1477 Error(StrBuf.str()); | 1479 Error(StrBuf.str()); |
| 1478 } | 1480 } |
| 1479 Ice::Operand *Elt = getRelativeOperand(Values[1], BaseIndex); | 1481 Ice::Operand *Elt = getRelativeOperand(Values[1], BaseIndex); |
| 1480 Ice::Type EltType = Elt->getType(); | 1482 Ice::Type EltType = Elt->getType(); |
| 1481 if (EltType != typeElementType(VecType)) { | 1483 if (EltType != typeElementType(VecType)) { |
| 1482 std::string Buffer; | 1484 std::string Buffer; |
| 1483 raw_string_ostream StrBuf(Buffer); | 1485 raw_string_ostream StrBuf(Buffer); |
| 1484 StrBuf << "Insertelement element not " << typeElementType(VecType) | 1486 StrBuf << "Insertelement element " << *Elt << " not type " |
| 1485 << ". Found: " << Elt; | 1487 << typeElementType(VecType) |
| 1488 << ". Found: " << EltType; |
| 1486 Error(StrBuf.str()); | 1489 Error(StrBuf.str()); |
| 1487 } | 1490 } |
| 1488 Ice::Operand *Index = getRelativeOperand(Values[2], BaseIndex); | 1491 Ice::Operand *Index = getRelativeOperand(Values[2], BaseIndex); |
| 1489 if (Index->getType() != Ice::IceType_i32) { | 1492 if (Index->getType() != Ice::IceType_i32) { |
| 1490 std::string Buffer; | 1493 std::string Buffer; |
| 1491 raw_string_ostream StrBuf(Buffer); | 1494 raw_string_ostream StrBuf(Buffer); |
| 1492 StrBuf << "Insertelement index not i32. Found: " << Index; | 1495 StrBuf << "Insertelement index " << *Index << " not i32. Found: " |
| 1496 << Index->getType(); |
| 1493 Error(StrBuf.str()); | 1497 Error(StrBuf.str()); |
| 1494 } | 1498 } |
| 1495 // TODO(kschimpf): Restrict index to a legal constant index (once | 1499 // TODO(kschimpf): Restrict index to a legal constant index (once |
| 1496 // constants can be defined). | 1500 // constants can be defined). |
| 1497 CurrentNode->appendInst(Ice::InstInsertElement::create( | 1501 CurrentNode->appendInst(Ice::InstInsertElement::create( |
| 1498 Func, getNextInstVar(EltType), Vec, Elt, Index)); | 1502 Func, getNextInstVar(EltType), Vec, Elt, Index)); |
| 1499 break; | 1503 break; |
| 1500 } | 1504 } |
| 1501 case naclbitc::FUNC_CODE_INST_CMP2: { | 1505 case naclbitc::FUNC_CODE_INST_CMP2: { |
| 1502 // CMP2: [opval, opval, pred] | 1506 // CMP2: [opval, opval, pred] |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1581 return; | 1585 return; |
| 1582 CurrentNode->appendInst(Ice::InstBr::create(Func, Block)); | 1586 CurrentNode->appendInst(Ice::InstBr::create(Func, Block)); |
| 1583 } else { | 1587 } else { |
| 1584 // BR: [bb#, bb#, opval] | 1588 // BR: [bb#, bb#, opval] |
| 1585 if (!isValidRecordSize(3, "function block branch")) | 1589 if (!isValidRecordSize(3, "function block branch")) |
| 1586 return; | 1590 return; |
| 1587 Ice::Operand *Cond = getRelativeOperand(Values[2], BaseIndex); | 1591 Ice::Operand *Cond = getRelativeOperand(Values[2], BaseIndex); |
| 1588 if (Cond->getType() != Ice::IceType_i1) { | 1592 if (Cond->getType() != Ice::IceType_i1) { |
| 1589 std::string Buffer; | 1593 std::string Buffer; |
| 1590 raw_string_ostream StrBuf(Buffer); | 1594 raw_string_ostream StrBuf(Buffer); |
| 1591 StrBuf << "Branch condition not i1"; | 1595 StrBuf << "Branch condition " << *Cond << " not i1. Found: " |
| 1596 << Cond->getType(); |
| 1592 Error(StrBuf.str()); | 1597 Error(StrBuf.str()); |
| 1593 return; | 1598 return; |
| 1594 } | 1599 } |
| 1595 Ice::CfgNode *ThenBlock = getBranchBasicBlock(Values[0]); | 1600 Ice::CfgNode *ThenBlock = getBranchBasicBlock(Values[0]); |
| 1596 Ice::CfgNode *ElseBlock = getBranchBasicBlock(Values[1]); | 1601 Ice::CfgNode *ElseBlock = getBranchBasicBlock(Values[1]); |
| 1597 if (ThenBlock == NULL || ElseBlock == NULL) | 1602 if (ThenBlock == NULL || ElseBlock == NULL) |
| 1598 return; | 1603 return; |
| 1599 CurrentNode->appendInst( | 1604 CurrentNode->appendInst( |
| 1600 Ice::InstBr::create(Func, Cond, ThenBlock, ElseBlock)); | 1605 Ice::InstBr::create(Func, Cond, ThenBlock, ElseBlock)); |
| 1601 } | 1606 } |
| 1602 InstIsTerminating = true; | 1607 InstIsTerminating = true; |
| 1603 break; | 1608 break; |
| 1604 } | 1609 } |
| 1610 case naclbitc::FUNC_CODE_INST_UNREACHABLE: { |
| 1611 // UNREACHABLE: [] |
| 1612 if (!isValidRecordSize(0, "function block unreachable")) |
| 1613 return; |
| 1614 CurrentNode->appendInst( |
| 1615 Ice::InstUnreachable::create(Func)); |
| 1616 InstIsTerminating = true; |
| 1617 break; |
| 1618 } |
| 1605 case naclbitc::FUNC_CODE_INST_PHI: { | 1619 case naclbitc::FUNC_CODE_INST_PHI: { |
| 1606 // PHI: [ty, val1, bb1, ..., valN, bbN] for n >= 2. | 1620 // PHI: [ty, val1, bb1, ..., valN, bbN] for n >= 2. |
| 1607 if (!isValidRecordSizeAtLeast(3, "function block phi")) | 1621 if (!isValidRecordSizeAtLeast(3, "function block phi")) |
| 1608 return; | 1622 return; |
| 1609 if ((Values.size() & 0x1) == 0) { | 1623 if ((Values.size() & 0x1) == 0) { |
| 1610 // Not an odd number of values. | 1624 // Not an odd number of values. |
| 1611 std::string Buffer; | 1625 std::string Buffer; |
| 1612 raw_string_ostream StrBuf(Buffer); | 1626 raw_string_ostream StrBuf(Buffer); |
| 1613 StrBuf << "function block phi record size not valid: " << Values.size(); | 1627 StrBuf << "function block phi record size not valid: " << Values.size(); |
| 1614 Error(StrBuf.str()); | 1628 Error(StrBuf.str()); |
| 1615 return; | 1629 return; |
| 1616 } | 1630 } |
| 1617 Ice::Type Ty = Context->convertToIceType(Context->getTypeByID(Values[0])); | 1631 Ice::Type Ty = Context->convertToIceType(Context->getTypeByID(Values[0])); |
| 1618 if (Ty == Ice::IceType_void) { | 1632 if (Ty == Ice::IceType_void) { |
| 1619 Error("Phi record using type void not allowed"); | 1633 Error("Phi record using type void not allowed"); |
| 1620 return; | 1634 return; |
| 1621 } | 1635 } |
| 1622 Ice::Variable *Dest = getNextInstVar(Ty); | 1636 Ice::Variable *Dest = getNextInstVar(Ty); |
| 1623 Ice::InstPhi *Phi = Ice::InstPhi::create(Func, Values.size() >> 1, Dest); | 1637 Ice::InstPhi *Phi = Ice::InstPhi::create(Func, Values.size() >> 1, Dest); |
| 1624 for (unsigned i = 1; i < Values.size(); i += 2) { | 1638 for (unsigned i = 1; i < Values.size(); i += 2) { |
| 1625 Ice::Operand *Op = | 1639 Ice::Operand *Op = |
| 1626 getRelativeOperand(NaClDecodeSignRotatedValue(Values[i]), BaseIndex); | 1640 getRelativeOperand(NaClDecodeSignRotatedValue(Values[i]), BaseIndex); |
| 1627 if (Op->getType() != Ty) { | 1641 if (Op->getType() != Ty) { |
| 1628 std::string Buffer; | 1642 std::string Buffer; |
| 1629 raw_string_ostream StrBuf(Buffer); | 1643 raw_string_ostream StrBuf(Buffer); |
| 1630 StrBuf << "Phi instruction expects type " << Ty << " but found: " << Op; | 1644 StrBuf << "Value " << *Op << " not type " << Ty |
| 1645 << " in phi instruction. Found: " << Op->getType(); |
| 1631 Error(StrBuf.str()); | 1646 Error(StrBuf.str()); |
| 1632 return; | 1647 return; |
| 1633 } | 1648 } |
| 1634 Phi->addArgument(Op, getBasicBlock(Values[i + 1])); | 1649 Phi->addArgument(Op, getBasicBlock(Values[i + 1])); |
| 1635 } | 1650 } |
| 1636 CurrentNode->appendInst(Phi); | 1651 CurrentNode->appendInst(Phi); |
| 1637 break; | 1652 break; |
| 1638 } | 1653 } |
| 1639 case naclbitc::FUNC_CODE_INST_ALLOCA: { | 1654 case naclbitc::FUNC_CODE_INST_ALLOCA: { |
| 1640 // ALLOCA: [Size, align] | 1655 // ALLOCA: [Size, align] |
| 1641 if (!isValidRecordSize(2, "function block alloca")) | 1656 if (!isValidRecordSize(2, "function block alloca")) |
| 1642 return; | 1657 return; |
| 1643 Ice::Operand *ByteCount = getRelativeOperand(Values[0], BaseIndex); | 1658 Ice::Operand *ByteCount = getRelativeOperand(Values[0], BaseIndex); |
| 1644 if (ByteCount->getType() != Ice::IceType_i32) { | 1659 if (ByteCount->getType() != Ice::IceType_i32) { |
| 1645 std::string Buffer; | 1660 std::string Buffer; |
| 1646 raw_string_ostream StrBuf(Buffer); | 1661 raw_string_ostream StrBuf(Buffer); |
| 1647 StrBuf << "Alloca on non-i32 value. Found: " << ByteCount; | 1662 StrBuf << "Alloca on non-i32 value. Found: " << *ByteCount; |
| 1648 Error(StrBuf.str()); | 1663 Error(StrBuf.str()); |
| 1649 return; | 1664 return; |
| 1650 } | 1665 } |
| 1651 unsigned Alignment; | 1666 unsigned Alignment; |
| 1652 extractAlignment("Alloca", Values[1], Alignment); | 1667 extractAlignment("Alloca", Values[1], Alignment); |
| 1653 CurrentNode->appendInst( | 1668 CurrentNode->appendInst( |
| 1654 Ice::InstAlloca::create(Func, ByteCount, Alignment, | 1669 Ice::InstAlloca::create(Func, ByteCount, Alignment, |
| 1655 getNextInstVar(Context->getIcePointerType()))); | 1670 getNextInstVar(Context->getIcePointerType()))); |
| 1656 break; | 1671 break; |
| 1657 } | 1672 } |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1680 return; | 1695 return; |
| 1681 Ice::Operand *Value = getRelativeOperand(Values[1], BaseIndex); | 1696 Ice::Operand *Value = getRelativeOperand(Values[1], BaseIndex); |
| 1682 unsigned Alignment; | 1697 unsigned Alignment; |
| 1683 extractAlignment("Store", Values[2], Alignment); | 1698 extractAlignment("Store", Values[2], Alignment); |
| 1684 if (!isValidLoadStoreAlignment(Alignment, Value->getType(), "Store")) | 1699 if (!isValidLoadStoreAlignment(Alignment, Value->getType(), "Store")) |
| 1685 return; | 1700 return; |
| 1686 CurrentNode->appendInst( | 1701 CurrentNode->appendInst( |
| 1687 Ice::InstStore::create(Func, Value, Address, Alignment)); | 1702 Ice::InstStore::create(Func, Value, Address, Alignment)); |
| 1688 break; | 1703 break; |
| 1689 } | 1704 } |
| 1705 case naclbitc::FUNC_CODE_INST_SWITCH: |
| 1706 case naclbitc::FUNC_CODE_INST_CALL: |
| 1707 case naclbitc::FUNC_CODE_INST_CALL_INDIRECT: |
| 1708 case naclbitc::FUNC_CODE_INST_FORWARDTYPEREF: |
| 1690 default: | 1709 default: |
| 1691 // Generate error message! | 1710 // Generate error message! |
| 1692 BlockParserBaseClass::ProcessRecord(); | 1711 BlockParserBaseClass::ProcessRecord(); |
| 1693 break; | 1712 break; |
| 1694 } | 1713 } |
| 1695 } | 1714 } |
| 1696 | 1715 |
| 1697 /// Parses constants within a function block. | 1716 /// Parses constants within a function block. |
| 1698 class ConstantsParser : public BlockParserBaseClass { | 1717 class ConstantsParser : public BlockParserBaseClass { |
| 1699 ConstantsParser(const ConstantsParser &) LLVM_DELETED_FUNCTION; | 1718 ConstantsParser(const ConstantsParser &) LLVM_DELETED_FUNCTION; |
| (...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2084 if (TopLevelBlocks != 1) { | 2103 if (TopLevelBlocks != 1) { |
| 2085 errs() << IRFilename | 2104 errs() << IRFilename |
| 2086 << ": Contains more than one module. Found: " << TopLevelBlocks | 2105 << ": Contains more than one module. Found: " << TopLevelBlocks |
| 2087 << "\n"; | 2106 << "\n"; |
| 2088 ErrorStatus = true; | 2107 ErrorStatus = true; |
| 2089 } | 2108 } |
| 2090 return; | 2109 return; |
| 2091 } | 2110 } |
| 2092 | 2111 |
| 2093 } // end of namespace Ice | 2112 } // end of namespace Ice |
| OLD | NEW |