Chromium Code Reviews| 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 |