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

Side by Side Diff: src/PNaClTranslator.cpp

Issue 561883002: Add load and store instructions to Subzero bitcode reader. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix isses in patch set 2. 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/IceTypes.def ('k') | tests_lit/reader_tests/load.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
11 // translator. 11 // translator.
12 // 12 //
13 //===----------------------------------------------------------------------===// 13 //===----------------------------------------------------------------------===//
14 14
15 #include "PNaClTranslator.h" 15 #include "PNaClTranslator.h"
16 #include "IceCfg.h" 16 #include "IceCfg.h"
17 #include "IceCfgNode.h" 17 #include "IceCfgNode.h"
18 #include "IceClFlags.h" 18 #include "IceClFlags.h"
19 #include "IceDefs.h" 19 #include "IceDefs.h"
20 #include "IceInst.h" 20 #include "IceInst.h"
21 #include "IceOperand.h" 21 #include "IceOperand.h"
22 #include "IceTypeConverter.h" 22 #include "IceTypeConverter.h"
23 #include "llvm/Analysis/NaCl/PNaClABIProps.h"
23 #include "llvm/Bitcode/NaCl/NaClBitcodeDecoders.h" 24 #include "llvm/Bitcode/NaCl/NaClBitcodeDecoders.h"
24 #include "llvm/Bitcode/NaCl/NaClBitcodeHeader.h" 25 #include "llvm/Bitcode/NaCl/NaClBitcodeHeader.h"
25 #include "llvm/Bitcode/NaCl/NaClBitcodeParser.h" 26 #include "llvm/Bitcode/NaCl/NaClBitcodeParser.h"
26 #include "llvm/Bitcode/NaCl/NaClReaderWriter.h" 27 #include "llvm/Bitcode/NaCl/NaClReaderWriter.h"
27 #include "llvm/IR/Constants.h" 28 #include "llvm/IR/Constants.h"
29 #include "llvm/IR/DataLayout.h"
28 #include "llvm/IR/LLVMContext.h" 30 #include "llvm/IR/LLVMContext.h"
29 #include "llvm/IR/Module.h" 31 #include "llvm/IR/Module.h"
30 #include "llvm/Support/Format.h" 32 #include "llvm/Support/Format.h"
31 #include "llvm/Support/MemoryBuffer.h" 33 #include "llvm/Support/MemoryBuffer.h"
32 #include "llvm/Support/raw_ostream.h" 34 #include "llvm/Support/raw_ostream.h"
33 #include "llvm/Support/ValueHandle.h" 35 #include "llvm/Support/ValueHandle.h"
34 36
35 #include <vector> 37 #include <vector>
36 #include <cassert> 38 #include <cassert>
37 39
(...skipping 10 matching lines...) Expand all
48 // Top-level class to read PNaCl bitcode files, and translate to ICE. 50 // Top-level class to read PNaCl bitcode files, and translate to ICE.
49 class TopLevelParser : public NaClBitcodeParser { 51 class TopLevelParser : public NaClBitcodeParser {
50 TopLevelParser(const TopLevelParser &) LLVM_DELETED_FUNCTION; 52 TopLevelParser(const TopLevelParser &) LLVM_DELETED_FUNCTION;
51 TopLevelParser &operator=(const TopLevelParser &) LLVM_DELETED_FUNCTION; 53 TopLevelParser &operator=(const TopLevelParser &) LLVM_DELETED_FUNCTION;
52 54
53 public: 55 public:
54 TopLevelParser(Ice::Translator &Translator, const std::string &InputName, 56 TopLevelParser(Ice::Translator &Translator, const std::string &InputName,
55 NaClBitcodeHeader &Header, NaClBitstreamCursor &Cursor, 57 NaClBitcodeHeader &Header, NaClBitstreamCursor &Cursor,
56 bool &ErrorStatus) 58 bool &ErrorStatus)
57 : NaClBitcodeParser(Cursor), Translator(Translator), 59 : NaClBitcodeParser(Cursor), Translator(Translator),
58 Mod(new Module(InputName, getGlobalContext())), Header(Header), 60 Mod(new Module(InputName, getGlobalContext())), DL(PNaClDataLayout),
59 TypeConverter(getLLVMContext()), ErrorStatus(ErrorStatus), NumErrors(0), 61 Header(Header), TypeConverter(getLLVMContext()),
60 NumFunctionIds(0), NumFunctionBlocks(0), 62 ErrorStatus(ErrorStatus), NumErrors(0), NumFunctionIds(0),
63 NumFunctionBlocks(0),
61 GlobalVarPlaceHolderType(convertToLLVMType(Ice::IceType_i8)) { 64 GlobalVarPlaceHolderType(convertToLLVMType(Ice::IceType_i8)) {
62 Mod->setDataLayout(PNaClDataLayout); 65 Mod->setDataLayout(PNaClDataLayout);
63 } 66 }
64 67
65 virtual ~TopLevelParser() {} 68 virtual ~TopLevelParser() {}
66 LLVM_OVERRIDE; 69 LLVM_OVERRIDE;
67 70
68 Ice::Translator &getTranslator() { return Translator; } 71 Ice::Translator &getTranslator() { return Translator; }
69 72
70 // Generates error with given Message. Always returns true. 73 // Generates error with given Message. Always returns true.
71 virtual bool Error(const std::string &Message) LLVM_OVERRIDE { 74 virtual bool Error(const std::string &Message) LLVM_OVERRIDE {
72 ErrorStatus = true; 75 ErrorStatus = true;
73 ++NumErrors; 76 ++NumErrors;
74 NaClBitcodeParser::Error(Message); 77 NaClBitcodeParser::Error(Message);
75 if (!AllowErrorRecovery) 78 if (!AllowErrorRecovery)
76 report_fatal_error("Unable to continue"); 79 report_fatal_error("Unable to continue");
77 return true; 80 return true;
78 } 81 }
79 82
80 /// Returns the number of errors found while parsing the bitcode 83 /// Returns the number of errors found while parsing the bitcode
81 /// file. 84 /// file.
82 unsigned getNumErrors() const { return NumErrors; } 85 unsigned getNumErrors() const { return NumErrors; }
83 86
84 /// Returns the LLVM module associated with the translation. 87 /// Returns the LLVM module associated with the translation.
85 Module *getModule() const { return Mod.get(); } 88 Module *getModule() const { return Mod.get(); }
86 89
90 const DataLayout &getDataLayout() const { return DL; }
91
87 /// Returns the number of bytes in the bitcode header. 92 /// Returns the number of bytes in the bitcode header.
88 size_t getHeaderSize() const { return Header.getHeaderSize(); } 93 size_t getHeaderSize() const { return Header.getHeaderSize(); }
89 94
90 /// Returns the llvm context to use. 95 /// Returns the llvm context to use.
91 LLVMContext &getLLVMContext() const { return Mod->getContext(); } 96 LLVMContext &getLLVMContext() const { return Mod->getContext(); }
92 97
93 /// Changes the size of the type list to the given size. 98 /// Changes the size of the type list to the given size.
94 void resizeTypeIDValues(unsigned NewSize) { TypeIDValues.resize(NewSize); } 99 void resizeTypeIDValues(unsigned NewSize) { TypeIDValues.resize(NewSize); }
95 100
96 /// Returns the type associated with the given index. 101 /// Returns the type associated with the given index.
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 /// Returns the model for pointer types in ICE. 226 /// Returns the model for pointer types in ICE.
222 Ice::Type getIcePointerType() const { 227 Ice::Type getIcePointerType() const {
223 return TypeConverter.getIcePointerType(); 228 return TypeConverter.getIcePointerType();
224 } 229 }
225 230
226 private: 231 private:
227 // The translator associated with the parser. 232 // The translator associated with the parser.
228 Ice::Translator &Translator; 233 Ice::Translator &Translator;
229 // The parsed module. 234 // The parsed module.
230 OwningPtr<Module> Mod; 235 OwningPtr<Module> Mod;
236 // The data layout to use.
237 DataLayout DL;
231 // The bitcode header. 238 // The bitcode header.
232 NaClBitcodeHeader &Header; 239 NaClBitcodeHeader &Header;
233 // Converter between LLVM and ICE types. 240 // Converter between LLVM and ICE types.
234 Ice::TypeConverter TypeConverter; 241 Ice::TypeConverter TypeConverter;
235 // The exit status that should be set to true if an error occurs. 242 // The exit status that should be set to true if an error occurs.
236 bool &ErrorStatus; 243 bool &ErrorStatus;
237 // The number of errors reported. 244 // The number of errors reported.
238 unsigned NumErrors; 245 unsigned NumErrors;
239 // The types associated with each type ID. 246 // The types associated with each type ID.
240 std::vector<Type *> TypeIDValues; 247 std::vector<Type *> TypeIDValues;
(...skipping 600 matching lines...) Expand 10 before | Expand all | Expand 10 after
841 // defined in the bitcode file. 848 // defined in the bitcode file.
842 std::vector<Ice::Operand *> LocalOperands; 849 std::vector<Ice::Operand *> LocalOperands;
843 // Holds the dividing point between local and global absolute value indices. 850 // Holds the dividing point between local and global absolute value indices.
844 uint32_t CachedNumGlobalValueIDs; 851 uint32_t CachedNumGlobalValueIDs;
845 // True if the last processed instruction was a terminating 852 // True if the last processed instruction was a terminating
846 // instruction. 853 // instruction.
847 bool InstIsTerminating; 854 bool InstIsTerminating;
848 // Upper limit of alignment power allowed by LLVM 855 // Upper limit of alignment power allowed by LLVM
849 static const uint64_t AlignPowerLimit = 29; 856 static const uint64_t AlignPowerLimit = 29;
850 857
858 // Extracts the corresponding Alignment to use, given the AlignPower
859 // (i.e. 2**AlignPower, or 0 if AlignPower == 0). InstName is the
860 // name of the instruction the alignment appears in.
861 void extractAlignment(const char *InstName, uint64_t AlignPower,
862 unsigned &Alignment) {
863 if (AlignPower <= AlignPowerLimit) {
864 Alignment = (1 << static_cast<unsigned>(AlignPower)) >> 1;
865 return;
866 }
867 std::string Buffer;
868 raw_string_ostream StrBuf(Buffer);
869 StrBuf << InstName << " alignment greater than 2**" << AlignPowerLimit
870 << ". Found: 2**" << AlignPower;
871 Error(StrBuf.str());
872 // Error recover with value that is always acceptable.
873 Alignment = 1;
874 }
875
851 virtual bool ParseBlock(unsigned BlockID) LLVM_OVERRIDE; 876 virtual bool ParseBlock(unsigned BlockID) LLVM_OVERRIDE;
852 877
853 virtual void ProcessRecord() LLVM_OVERRIDE; 878 virtual void ProcessRecord() LLVM_OVERRIDE;
854 879
855 virtual void ExitBlock() LLVM_OVERRIDE; 880 virtual void ExitBlock() LLVM_OVERRIDE;
856 881
857 // Creates and appends a new basic block to the list of basic blocks. 882 // Creates and appends a new basic block to the list of basic blocks.
858 Ice::CfgNode *InstallNextBasicBlock() { return Func->makeNode(); } 883 Ice::CfgNode *InstallNextBasicBlock() { return Func->makeNode(); }
859 884
860 // Returns the Index-th basic block in the list of basic blocks. 885 // Returns the Index-th basic block in the list of basic blocks.
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
952 // OpTy, is valid. Returns true if valid. Otherwise generates 977 // OpTy, is valid. Returns true if valid. Otherwise generates
953 // error message and returns false. 978 // error message and returns false.
954 bool isValidIntegerArithOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) { 979 bool isValidIntegerArithOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) {
955 if (Ice::isIntegerArithmeticType(OpTy)) 980 if (Ice::isIntegerArithmeticType(OpTy))
956 return true; 981 return true;
957 ReportInvalidBinaryOp(Op, OpTy); 982 ReportInvalidBinaryOp(Op, OpTy);
958 return false; 983 return false;
959 } 984 }
960 985
961 // Checks if floating arithmetic Op, for type OpTy, is valid. 986 // Checks if floating arithmetic Op, for type OpTy, is valid.
962 // Returns false if valid. Otherwise generates an error message and 987 // Returns true if valid. Otherwise generates an error message and
963 // returns true. 988 // returns false;
964 bool isValidFloatingArithOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) { 989 bool isValidFloatingArithOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) {
965 if (Ice::isFloatingType(OpTy)) 990 if (Ice::isFloatingType(OpTy))
966 return true; 991 return true;
967 ReportInvalidBinaryOp(Op, OpTy); 992 ReportInvalidBinaryOp(Op, OpTy);
968 return false; 993 return false;
969 } 994 }
970 995
996 // Checks if the type of operand Op is the valid pointer type, for
997 // the given InstructionName. Returns true if valid. Otherwise
998 // generates an error message and returns false.
999 bool isValidPointerType(Ice::Operand *Op, const char *InstructionName) {
1000 Ice::Type PtrType = Context->getIcePointerType();
1001 if (Op->getType() == PtrType)
1002 return true;
1003 std::string Buffer;
1004 raw_string_ostream StrBuf(Buffer);
1005 StrBuf << InstructionName << " address not " << PtrType
1006 << ". Found: " << Op;
1007 Error(StrBuf.str());
1008 return false;
1009 }
1010
1011 // Checks if loading/storing a value of type Ty is allowed.
1012 // Returns true if Valid. Otherwise generates an error message and
1013 // returns false.
1014 bool isValidLoadStoreType(Ice::Type Ty, const char *InstructionName) {
1015 if (isLoadStoreType(Ty))
1016 return true;
1017 std::string Buffer;
1018 raw_string_ostream StrBuf(Buffer);
1019 StrBuf << InstructionName << " type not allowed: " << Ty << "*";
1020 Error(StrBuf.str());
1021 return false;
1022 }
1023
1024 // Checks if loading/storing a value of type Ty is allowed for
1025 // the given Alignment. Otherwise generates an error message and
1026 // returns false.
1027 bool isValidLoadStoreAlignment(unsigned Alignment, Ice::Type Ty,
1028 const char *InstructionName) {
1029 if (!isValidLoadStoreType(Ty, InstructionName))
1030 return false;
1031 if (PNaClABIProps::isAllowedAlignment(&Context->getDataLayout(), Alignment,
1032 Context->convertToLLVMType(Ty)))
1033 return true;
1034 std::string Buffer;
1035 raw_string_ostream StrBuf(Buffer);
1036 StrBuf << InstructionName << " " << Ty << "*: not allowed for alignment "
1037 << Alignment;
1038 Error(StrBuf.str());
1039 return false;
1040 }
1041
971 // Reports that the given binary Opcode, for the given type Ty, 1042 // Reports that the given binary Opcode, for the given type Ty,
972 // is not understood. 1043 // is not understood.
973 void ReportInvalidBinopOpcode(unsigned Opcode, Ice::Type Ty); 1044 void ReportInvalidBinopOpcode(unsigned Opcode, Ice::Type Ty);
974 1045
975 // Takes the PNaCl bitcode binary operator Opcode, and the opcode 1046 // Takes the PNaCl bitcode binary operator Opcode, and the opcode
976 // type Ty, and sets Op to the corresponding ICE binary 1047 // type Ty, and sets Op to the corresponding ICE binary
977 // opcode. Returns true if able to convert, false otherwise. 1048 // opcode. Returns true if able to convert, false otherwise.
978 bool convertBinopOpcode(unsigned Opcode, Ice::Type Ty, 1049 bool convertBinopOpcode(unsigned Opcode, Ice::Type Ty,
979 Ice::InstArithmetic::OpKind &Op) { 1050 Ice::InstArithmetic::OpKind &Op) {
980 Instruction::BinaryOps LLVMOpcode; 1051 Instruction::BinaryOps LLVMOpcode;
(...skipping 541 matching lines...) Expand 10 before | Expand all | Expand 10 after
1522 if (!isValidRecordSize(2, "function block alloca")) 1593 if (!isValidRecordSize(2, "function block alloca"))
1523 return; 1594 return;
1524 Ice::Operand *ByteCount = getRelativeOperand(Values[0]); 1595 Ice::Operand *ByteCount = getRelativeOperand(Values[0]);
1525 if (ByteCount->getType() != Ice::IceType_i32) { 1596 if (ByteCount->getType() != Ice::IceType_i32) {
1526 std::string Buffer; 1597 std::string Buffer;
1527 raw_string_ostream StrBuf(Buffer); 1598 raw_string_ostream StrBuf(Buffer);
1528 StrBuf << "Alloca on non-i32 value. Found: " << ByteCount; 1599 StrBuf << "Alloca on non-i32 value. Found: " << ByteCount;
1529 Error(StrBuf.str()); 1600 Error(StrBuf.str());
1530 return; 1601 return;
1531 } 1602 }
1532 uint64_t AlignPower = Values[1]; 1603 unsigned Alignment;
1533 unsigned Alignment = 1; 1604 extractAlignment("Alloca", Values[1], Alignment);
1534 if (AlignPower <= AlignPowerLimit) {
1535 Alignment = (1 << static_cast<unsigned>(AlignPower)) >> 1;
1536 } else {
1537 std::string Buffer;
1538 raw_string_ostream StrBuf(Buffer);
1539 StrBuf << "Alloca on alignment greater than 2**" << AlignPowerLimit
1540 << ". Found: 2**" << AlignPower;
1541 Error(StrBuf.str());
1542 // TODO(kschimpf) Remove error recovery once implementation complete.
1543 }
1544 Ice::Variable *Dest = NextInstVar(Context->getIcePointerType()); 1605 Ice::Variable *Dest = NextInstVar(Context->getIcePointerType());
1545 Inst = Ice::InstAlloca::create(Func, ByteCount, Alignment, Dest); 1606 Inst = Ice::InstAlloca::create(Func, ByteCount, Alignment, Dest);
1546 break; 1607 break;
1547 } 1608 }
1609 case naclbitc::FUNC_CODE_INST_LOAD: {
1610 // LOAD: [address, align, ty]
1611 if (!isValidRecordSize(3, "function block load"))
1612 return;
1613 Ice::Operand *Address = getRelativeOperand(Values[0]);
1614 if (!isValidPointerType(Address, "Load"))
1615 return;
1616 unsigned Alignment;
1617 extractAlignment("Load", Values[1], Alignment);
1618 Ice::Type Ty = Context->convertToIceType(Context->getTypeByID(Values[2]));
1619 if (!isValidLoadStoreAlignment(Alignment, Ty, "Load"))
1620 return;
1621 Ice::Variable *Dest = NextInstVar(Ty);
1622 Inst = Ice::InstLoad::create(Func, Dest, Address, Alignment);
1623 break;
1624 }
1625 case naclbitc::FUNC_CODE_INST_STORE: {
1626 // STORE: [address, value, align]
1627 if (!isValidRecordSize(3, "function block store"))
1628 return;
1629 Ice::Operand *Address = getRelativeOperand(Values[0]);
1630 if (!isValidPointerType(Address, "Store"))
1631 return;
1632 Ice::Operand *Value = getRelativeOperand(Values[1]);
1633 unsigned Alignment;
1634 if (!extractAlignment("Store", Values[2], Alignment)) {
1635 // TODO(kschimpf) Remove error recovery once implementation complete.
1636 Alignment = 1;
1637 }
1638 if (!isValidLoadStoreAlignment(Alignment, Value->getType(), "Store"))
1639 return;
1640 Inst = Ice::InstStore::create(Func, Value, Address, Alignment);
1641 break;
1642 }
1548 default: 1643 default:
1549 // Generate error message! 1644 // Generate error message!
1550 BlockParserBaseClass::ProcessRecord(); 1645 BlockParserBaseClass::ProcessRecord();
1551 break; 1646 break;
1552 } 1647 }
1553 if (Inst) 1648 if (Inst)
1554 CurrentNode->appendInst(Inst); 1649 CurrentNode->appendInst(Inst);
1555 } 1650 }
1556 1651
1557 /// Parses constants within a function block. 1652 /// Parses constants within a function block.
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
1836 if (TopLevelBlocks != 1) { 1931 if (TopLevelBlocks != 1) {
1837 errs() << IRFilename 1932 errs() << IRFilename
1838 << ": Contains more than one module. Found: " << TopLevelBlocks 1933 << ": Contains more than one module. Found: " << TopLevelBlocks
1839 << "\n"; 1934 << "\n";
1840 ErrorStatus = true; 1935 ErrorStatus = true;
1841 } 1936 }
1842 return; 1937 return;
1843 } 1938 }
1844 1939
1845 } // end of namespace Ice 1940 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceTypes.def ('k') | tests_lit/reader_tests/load.ll » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698