Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1195)

Side by Side Diff: src/PNaClTranslator.cpp

Issue 577703002: Add unreachable instruction to Subzero. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix nits. Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/IceOperand.h ('k') | tests_lit/reader_tests/unreachable.ll » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/IceOperand.h ('k') | tests_lit/reader_tests/unreachable.ll » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698