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; |
Jim Stichnoth
2014/09/16 20:16:31
Did you mean to delete the space before 'not'?
Karl
2014/09/16 20:35:54
Yes. Added.
| |
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"; |
Jim Stichnoth
2014/09/16 20:16:31
Print the actual operand type as well as the opera
Karl
2014/09/16 20:35:54
Done.
| |
1592 Error(StrBuf.str()); | 1596 Error(StrBuf.str()); |
1593 return; | 1597 return; |
1594 } | 1598 } |
1595 Ice::CfgNode *ThenBlock = getBranchBasicBlock(Values[0]); | 1599 Ice::CfgNode *ThenBlock = getBranchBasicBlock(Values[0]); |
1596 Ice::CfgNode *ElseBlock = getBranchBasicBlock(Values[1]); | 1600 Ice::CfgNode *ElseBlock = getBranchBasicBlock(Values[1]); |
1597 if (ThenBlock == NULL || ElseBlock == NULL) | 1601 if (ThenBlock == NULL || ElseBlock == NULL) |
1598 return; | 1602 return; |
1599 CurrentNode->appendInst( | 1603 CurrentNode->appendInst( |
1600 Ice::InstBr::create(Func, Cond, ThenBlock, ElseBlock)); | 1604 Ice::InstBr::create(Func, Cond, ThenBlock, ElseBlock)); |
1601 } | 1605 } |
(...skipping 18 matching lines...) Expand all Loading... | |
1620 return; | 1624 return; |
1621 } | 1625 } |
1622 Ice::Variable *Dest = getNextInstVar(Ty); | 1626 Ice::Variable *Dest = getNextInstVar(Ty); |
1623 Ice::InstPhi *Phi = Ice::InstPhi::create(Func, Values.size() >> 1, Dest); | 1627 Ice::InstPhi *Phi = Ice::InstPhi::create(Func, Values.size() >> 1, Dest); |
1624 for (unsigned i = 1; i < Values.size(); i += 2) { | 1628 for (unsigned i = 1; i < Values.size(); i += 2) { |
1625 Ice::Operand *Op = | 1629 Ice::Operand *Op = |
1626 getRelativeOperand(NaClDecodeSignRotatedValue(Values[i]), BaseIndex); | 1630 getRelativeOperand(NaClDecodeSignRotatedValue(Values[i]), BaseIndex); |
1627 if (Op->getType() != Ty) { | 1631 if (Op->getType() != Ty) { |
1628 std::string Buffer; | 1632 std::string Buffer; |
1629 raw_string_ostream StrBuf(Buffer); | 1633 raw_string_ostream StrBuf(Buffer); |
1630 StrBuf << "Phi instruction expects type " << Ty << " but found: " << Op; | 1634 StrBuf << "Value " << *Op << " not type " << Ty |
1635 << " in phi instruction"; | |
Jim Stichnoth
2014/09/16 20:16:31
Print actual operand type?
Karl
2014/09/16 20:35:54
Done.
| |
1631 Error(StrBuf.str()); | 1636 Error(StrBuf.str()); |
1632 return; | 1637 return; |
1633 } | 1638 } |
1634 Phi->addArgument(Op, getBasicBlock(Values[i + 1])); | 1639 Phi->addArgument(Op, getBasicBlock(Values[i + 1])); |
1635 } | 1640 } |
1636 CurrentNode->appendInst(Phi); | 1641 CurrentNode->appendInst(Phi); |
1637 break; | 1642 break; |
1638 } | 1643 } |
1639 case naclbitc::FUNC_CODE_INST_ALLOCA: { | 1644 case naclbitc::FUNC_CODE_INST_ALLOCA: { |
1640 // ALLOCA: [Size, align] | 1645 // ALLOCA: [Size, align] |
1641 if (!isValidRecordSize(2, "function block alloca")) | 1646 if (!isValidRecordSize(2, "function block alloca")) |
1642 return; | 1647 return; |
1643 Ice::Operand *ByteCount = getRelativeOperand(Values[0], BaseIndex); | 1648 Ice::Operand *ByteCount = getRelativeOperand(Values[0], BaseIndex); |
1644 if (ByteCount->getType() != Ice::IceType_i32) { | 1649 if (ByteCount->getType() != Ice::IceType_i32) { |
1645 std::string Buffer; | 1650 std::string Buffer; |
1646 raw_string_ostream StrBuf(Buffer); | 1651 raw_string_ostream StrBuf(Buffer); |
1647 StrBuf << "Alloca on non-i32 value. Found: " << ByteCount; | 1652 StrBuf << "Alloca on non-i32 value. Found: " << *ByteCount; |
1648 Error(StrBuf.str()); | 1653 Error(StrBuf.str()); |
1649 return; | 1654 return; |
1650 } | 1655 } |
1651 unsigned Alignment; | 1656 unsigned Alignment; |
1652 extractAlignment("Alloca", Values[1], Alignment); | 1657 extractAlignment("Alloca", Values[1], Alignment); |
1653 CurrentNode->appendInst( | 1658 CurrentNode->appendInst( |
1654 Ice::InstAlloca::create(Func, ByteCount, Alignment, | 1659 Ice::InstAlloca::create(Func, ByteCount, Alignment, |
1655 getNextInstVar(Context->getIcePointerType()))); | 1660 getNextInstVar(Context->getIcePointerType()))); |
1656 break; | 1661 break; |
1657 } | 1662 } |
1658 case naclbitc::FUNC_CODE_INST_LOAD: { | 1663 case naclbitc::FUNC_CODE_INST_LOAD: { |
1659 // LOAD: [address, align, ty] | 1664 // LOAD: [address, align, ty] |
1660 if (!isValidRecordSize(3, "function block load")) | 1665 if (!isValidRecordSize(3, "function block load")) |
1661 return; | 1666 return; |
1662 Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex); | 1667 Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex); |
1663 if (!isValidPointerType(Address, "Load")) | 1668 if (!isValidPointerType(Address, "Load")) |
1664 return; | 1669 return; |
1665 unsigned Alignment; | 1670 unsigned Alignment; |
1666 extractAlignment("Load", Values[1], Alignment); | 1671 extractAlignment("Load", Values[1], Alignment); |
1667 Ice::Type Ty = Context->convertToIceType(Context->getTypeByID(Values[2])); | 1672 Ice::Type Ty = Context->convertToIceType(Context->getTypeByID(Values[2])); |
1668 if (!isValidLoadStoreAlignment(Alignment, Ty, "Load")) | 1673 if (!isValidLoadStoreAlignment(Alignment, Ty, "Load")) |
1669 return; | 1674 return; |
1670 CurrentNode->appendInst( | 1675 CurrentNode->appendInst( |
1671 Ice::InstLoad::create(Func, getNextInstVar(Ty), Address, Alignment)); | 1676 Ice::InstLoad::create(Func, getNextInstVar(Ty), Address, Alignment)); |
1672 break; | 1677 break; |
1673 } | 1678 } |
1679 case naclbitc::FUNC_CODE_INST_UNREACHABLE: { | |
Jim Stichnoth
2014/09/16 20:16:31
Would you mind explicitly enumerating all the curr
Karl
2014/09/16 20:35:54
Done.
| |
1680 // UNREACHABLE: [] | |
1681 if (!isValidRecordSize(0, "function block unreachable")) | |
1682 return; | |
1683 CurrentNode->appendInst( | |
1684 Ice::InstUnreachable::create(Func)); | |
1685 InstIsTerminating = true; | |
1686 break; | |
1687 } | |
1674 case naclbitc::FUNC_CODE_INST_STORE: { | 1688 case naclbitc::FUNC_CODE_INST_STORE: { |
1675 // STORE: [address, value, align] | 1689 // STORE: [address, value, align] |
1676 if (!isValidRecordSize(3, "function block store")) | 1690 if (!isValidRecordSize(3, "function block store")) |
1677 return; | 1691 return; |
1678 Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex); | 1692 Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex); |
1679 if (!isValidPointerType(Address, "Store")) | 1693 if (!isValidPointerType(Address, "Store")) |
1680 return; | 1694 return; |
1681 Ice::Operand *Value = getRelativeOperand(Values[1], BaseIndex); | 1695 Ice::Operand *Value = getRelativeOperand(Values[1], BaseIndex); |
1682 unsigned Alignment; | 1696 unsigned Alignment; |
1683 extractAlignment("Store", Values[2], Alignment); | 1697 extractAlignment("Store", Values[2], Alignment); |
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2084 if (TopLevelBlocks != 1) { | 2098 if (TopLevelBlocks != 1) { |
2085 errs() << IRFilename | 2099 errs() << IRFilename |
2086 << ": Contains more than one module. Found: " << TopLevelBlocks | 2100 << ": Contains more than one module. Found: " << TopLevelBlocks |
2087 << "\n"; | 2101 << "\n"; |
2088 ErrorStatus = true; | 2102 ErrorStatus = true; |
2089 } | 2103 } |
2090 return; | 2104 return; |
2091 } | 2105 } |
2092 | 2106 |
2093 } // end of namespace Ice | 2107 } // end of namespace Ice |
OLD | NEW |