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 |