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

Side by Side Diff: src/PNaClTranslator.cpp

Issue 577353003: Add call instructions to Subzero's bitcode reader. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix remaining issues raised. 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/IceTargetLoweringX8632.h ('k') | tests_lit/reader_tests/call.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 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 TopLevelParser(Ice::Translator &Translator, const std::string &InputName, 56 TopLevelParser(Ice::Translator &Translator, const std::string &InputName,
57 NaClBitcodeHeader &Header, NaClBitstreamCursor &Cursor, 57 NaClBitcodeHeader &Header, NaClBitstreamCursor &Cursor,
58 bool &ErrorStatus) 58 bool &ErrorStatus)
59 : NaClBitcodeParser(Cursor), Translator(Translator), 59 : NaClBitcodeParser(Cursor), Translator(Translator),
60 Mod(new Module(InputName, getGlobalContext())), DL(PNaClDataLayout), 60 Mod(new Module(InputName, getGlobalContext())), DL(PNaClDataLayout),
61 Header(Header), TypeConverter(getLLVMContext()), 61 Header(Header), TypeConverter(getLLVMContext()),
62 ErrorStatus(ErrorStatus), NumErrors(0), NumFunctionIds(0), 62 ErrorStatus(ErrorStatus), NumErrors(0), NumFunctionIds(0),
63 NumFunctionBlocks(0), 63 NumFunctionBlocks(0),
64 GlobalVarPlaceHolderType(convertToLLVMType(Ice::IceType_i8)) { 64 GlobalVarPlaceHolderType(convertToLLVMType(Ice::IceType_i8)) {
65 Mod->setDataLayout(PNaClDataLayout); 65 Mod->setDataLayout(PNaClDataLayout);
66 setErrStream(Translator.getContext()->getStrDump());
66 } 67 }
67 68
68 virtual ~TopLevelParser() {} 69 virtual ~TopLevelParser() {}
69 LLVM_OVERRIDE; 70 LLVM_OVERRIDE;
70 71
71 Ice::Translator &getTranslator() { return Translator; } 72 Ice::Translator &getTranslator() { return Translator; }
72 73
73 // Generates error with given Message. Always returns true. 74 // Generates error with given Message. Always returns true.
74 virtual bool Error(const std::string &Message) LLVM_OVERRIDE { 75 virtual bool Error(const std::string &Message) LLVM_OVERRIDE {
75 ErrorStatus = true; 76 ErrorStatus = true;
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 return DefiningFunctionsList[NumFunctionBlocks++]; 140 return DefiningFunctionsList[NumFunctionBlocks++];
140 } 141 }
141 142
142 /// Returns the LLVM IR value associatd with the global value ID. 143 /// Returns the LLVM IR value associatd with the global value ID.
143 Value *getGlobalValueByID(unsigned ID) const { 144 Value *getGlobalValueByID(unsigned ID) const {
144 if (ID >= ValueIDValues.size()) 145 if (ID >= ValueIDValues.size())
145 return NULL; 146 return NULL;
146 return ValueIDValues[ID]; 147 return ValueIDValues[ID];
147 } 148 }
148 149
150 /// Returns the corresponding constant associated with a global value
151 /// (i.e. relocatable).
152 Ice::Constant *getOrCreateGlobalConstantByID(unsigned ID) {
153 // TODO(kschimpf): Can this be built when creating global initializers?
154 if (ID >= ValueIDConstants.size()) {
155 if (ID >= ValueIDValues.size())
156 return NULL;
157 ValueIDConstants.resize(ValueIDValues.size());
158 }
159 Ice::Constant *C = ValueIDConstants[ID];
160 if (C != NULL)
161 return C;
162 Value *V = ValueIDValues[ID];
163 assert(isa<GlobalValue>(V));
164 C = getTranslator().getContext()->getConstantSym(getIcePointerType(), 0,
165 V->getName());
166 ValueIDConstants[ID] = C;
167 return C;
168 }
169
149 /// Returns the number of function addresses (i.e. ID's) defined in 170 /// Returns the number of function addresses (i.e. ID's) defined in
150 /// the bitcode file. 171 /// the bitcode file.
151 unsigned getNumFunctionIDs() const { return NumFunctionIds; } 172 unsigned getNumFunctionIDs() const { return NumFunctionIds; }
152 173
153 /// Returns the number of global values defined in the bitcode 174 /// Returns the number of global values defined in the bitcode
154 /// file. 175 /// file.
155 unsigned getNumGlobalValueIDs() const { return ValueIDValues.size(); } 176 unsigned getNumGlobalValueIDs() const { return ValueIDValues.size(); }
156 177
157 /// Resizes the list of value IDs to include Count global variable 178 /// Resizes the list of value IDs to include Count global variable
158 /// IDs. 179 /// IDs.
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 // Converter between LLVM and ICE types. 261 // Converter between LLVM and ICE types.
241 Ice::TypeConverter TypeConverter; 262 Ice::TypeConverter TypeConverter;
242 // The exit status that should be set to true if an error occurs. 263 // The exit status that should be set to true if an error occurs.
243 bool &ErrorStatus; 264 bool &ErrorStatus;
244 // The number of errors reported. 265 // The number of errors reported.
245 unsigned NumErrors; 266 unsigned NumErrors;
246 // The types associated with each type ID. 267 // The types associated with each type ID.
247 std::vector<Type *> TypeIDValues; 268 std::vector<Type *> TypeIDValues;
248 // The (global) value IDs. 269 // The (global) value IDs.
249 std::vector<WeakVH> ValueIDValues; 270 std::vector<WeakVH> ValueIDValues;
271 // Relocatable constants associated with ValueIDValues.
272 std::vector<Ice::Constant *> ValueIDConstants;
250 // The number of function IDs. 273 // The number of function IDs.
251 unsigned NumFunctionIds; 274 unsigned NumFunctionIds;
252 // The number of function blocks (processed so far). 275 // The number of function blocks (processed so far).
253 unsigned NumFunctionBlocks; 276 unsigned NumFunctionBlocks;
254 // The list of value IDs (in the order found) of defining function 277 // The list of value IDs (in the order found) of defining function
255 // addresses. 278 // addresses.
256 std::vector<unsigned> DefiningFunctionsList; 279 std::vector<unsigned> DefiningFunctionsList;
257 // Cached global variable placeholder type. Used for all forward 280 // Cached global variable placeholder type. Used for all forward
258 // references to global variable addresses. 281 // references to global variable addresses.
259 Type *GlobalVarPlaceHolderType; 282 Type *GlobalVarPlaceHolderType;
(...skipping 706 matching lines...) Expand 10 before | Expand all | Expand 10 after
966 Error(StrBuf.str()); 989 Error(StrBuf.str());
967 // TODO(kschimpf) Remove error recovery once implementation complete. 990 // TODO(kschimpf) Remove error recovery once implementation complete.
968 return 0; 991 return 0;
969 } 992 }
970 return BaseIndex - Id; 993 return BaseIndex - Id;
971 } 994 }
972 995
973 // Returns the value referenced by the given value Index. 996 // Returns the value referenced by the given value Index.
974 Ice::Operand *getOperand(uint32_t Index) { 997 Ice::Operand *getOperand(uint32_t Index) {
975 if (Index < CachedNumGlobalValueIDs) { 998 if (Index < CachedNumGlobalValueIDs) {
976 // TODO(kschimpf): Define implementation. 999 return Context->getOrCreateGlobalConstantByID(Index);
977 report_fatal_error("getOperand of global addresses not implemented");
978 } 1000 }
979 uint32_t LocalIndex = Index - CachedNumGlobalValueIDs; 1001 uint32_t LocalIndex = Index - CachedNumGlobalValueIDs;
980 if (LocalIndex >= LocalOperands.size()) { 1002 if (LocalIndex >= LocalOperands.size()) {
981 std::string Buffer; 1003 std::string Buffer;
982 raw_string_ostream StrBuf(Buffer); 1004 raw_string_ostream StrBuf(Buffer);
983 StrBuf << "Value index " << Index << " not defined!"; 1005 StrBuf << "Value index " << Index << " not defined!";
984 Error(StrBuf.str()); 1006 Error(StrBuf.str());
985 report_fatal_error("Unable to continue"); 1007 report_fatal_error("Unable to continue");
986 } 1008 }
987 Ice::Operand *Op = LocalOperands[LocalIndex]; 1009 Ice::Operand *Op = LocalOperands[LocalIndex];
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
1116 StrBuf << InstructionName << " " << Ty << "*: not allowed for alignment " 1138 StrBuf << InstructionName << " " << Ty << "*: not allowed for alignment "
1117 << Alignment; 1139 << Alignment;
1118 Error(StrBuf.str()); 1140 Error(StrBuf.str());
1119 return false; 1141 return false;
1120 } 1142 }
1121 1143
1122 // Reports that the given binary Opcode, for the given type Ty, 1144 // Reports that the given binary Opcode, for the given type Ty,
1123 // is not understood. 1145 // is not understood.
1124 void ReportInvalidBinopOpcode(unsigned Opcode, Ice::Type Ty); 1146 void ReportInvalidBinopOpcode(unsigned Opcode, Ice::Type Ty);
1125 1147
1148 // Returns true if the Str begins with Prefix.
1149 bool isStringPrefix(Ice::IceString &Str, Ice::IceString &Prefix) {
1150 const size_t PrefixSize = Prefix.size();
1151 if (Str.size() < PrefixSize)
1152 return false;
1153 for (size_t i = 0; i < PrefixSize; ++i) {
1154 if (Str[i] != Prefix[i])
1155 return false;
1156 }
1157 return true;
1158 }
1159
1126 // Takes the PNaCl bitcode binary operator Opcode, and the opcode 1160 // Takes the PNaCl bitcode binary operator Opcode, and the opcode
1127 // type Ty, and sets Op to the corresponding ICE binary 1161 // type Ty, and sets Op to the corresponding ICE binary
1128 // opcode. Returns true if able to convert, false otherwise. 1162 // opcode. Returns true if able to convert, false otherwise.
1129 bool convertBinopOpcode(unsigned Opcode, Ice::Type Ty, 1163 bool convertBinopOpcode(unsigned Opcode, Ice::Type Ty,
1130 Ice::InstArithmetic::OpKind &Op) { 1164 Ice::InstArithmetic::OpKind &Op) {
1131 Instruction::BinaryOps LLVMOpcode; 1165 Instruction::BinaryOps LLVMOpcode;
1132 if (!naclbitc::DecodeBinaryOpcode(Opcode, Context->convertToLLVMType(Ty), 1166 if (!naclbitc::DecodeBinaryOpcode(Opcode, Context->convertToLLVMType(Ty),
1133 LLVMOpcode)) { 1167 LLVMOpcode)) {
1134 ReportInvalidBinopOpcode(Opcode, Ty); 1168 ReportInvalidBinopOpcode(Opcode, Ty);
1135 // TODO(kschimpf) Remove error recovery once implementation complete. 1169 // TODO(kschimpf) Remove error recovery once implementation complete.
(...skipping 691 matching lines...) Expand 10 before | Expand all | Expand 10 after
1827 return; 1861 return;
1828 Ice::Operand *Value = getRelativeOperand(Values[1], BaseIndex); 1862 Ice::Operand *Value = getRelativeOperand(Values[1], BaseIndex);
1829 unsigned Alignment; 1863 unsigned Alignment;
1830 extractAlignment("Store", Values[2], Alignment); 1864 extractAlignment("Store", Values[2], Alignment);
1831 if (!isValidLoadStoreAlignment(Alignment, Value->getType(), "Store")) 1865 if (!isValidLoadStoreAlignment(Alignment, Value->getType(), "Store"))
1832 return; 1866 return;
1833 CurrentNode->appendInst( 1867 CurrentNode->appendInst(
1834 Ice::InstStore::create(Func, Value, Address, Alignment)); 1868 Ice::InstStore::create(Func, Value, Address, Alignment));
1835 break; 1869 break;
1836 } 1870 }
1871 case naclbitc::FUNC_CODE_INST_CALL:
1872 case naclbitc::FUNC_CODE_INST_CALL_INDIRECT: {
1873 // CALL: [cc, fnid, arg0, arg1...]
1874 // CALL_INDIRECT: [cc, fn, returnty, args...]
1875 //
1876 // Note: The difference between CALL and CALL_INDIRECT is that
1877 // CALL has an explicit function address, while the CALL_INDIRECT
1878 // is just an address. For CALL, we can infer the return type by
1879 // looking up the type signature associated with the function
1880 // address. For CALL_INDIRECT we can only infer the type signature
1881 // via argument types, and the corresponding return type stored in
1882 // CALL_INDIRECT record.
1883 Ice::SizeT ParamsStartIndex = 2;
1884 if (Record.GetCode() == naclbitc::FUNC_CODE_INST_CALL) {
1885 if (!isValidRecordSizeAtLeast(2, "function block call"))
1886 return;
1887 } else {
1888 if (!isValidRecordSizeAtLeast(3, "function block call indirect"))
1889 return;
1890 ParamsStartIndex = 3;
1891 }
1892
1893 // Extract call information.
1894 uint64_t CCInfo = Values[0];
1895 CallingConv::ID CallingConv;
1896 if (!naclbitc::DecodeCallingConv(CCInfo >> 1, CallingConv)) {
1897 std::string Buffer;
1898 raw_string_ostream StrBuf(Buffer);
1899 StrBuf << "Function call calling convention value " << (CCInfo >> 1)
1900 << " not understood.";
1901 Error(StrBuf.str());
1902 return;
1903 }
1904 bool IsTailCall = static_cast<bool>(CCInfo & 1);
1905
1906 // Extract out the called function and its return type.
1907 uint32_t CalleeIndex = convertRelativeToAbsIndex(Values[1], BaseIndex);
1908 Ice::Operand *Callee = getOperand(CalleeIndex);
1909 Ice::Type ReturnType = Ice::IceType_void;
1910 const Ice::Intrinsics::FullIntrinsicInfo *IntrinsicInfo = NULL;
1911 if (Record.GetCode() == naclbitc::FUNC_CODE_INST_CALL) {
1912 Function *Fcn =
1913 dyn_cast<Function>(Context->getGlobalValueByID(CalleeIndex));
1914 if (Fcn == NULL) {
1915 std::string Buffer;
1916 raw_string_ostream StrBuf(Buffer);
1917 StrBuf << "Function call to non-function: " << *Callee;
1918 Error(StrBuf.str());
1919 return;
1920 }
1921
1922 FunctionType *FcnTy = Fcn->getFunctionType();
1923 ReturnType = Context->convertToIceType(FcnTy->getReturnType());
1924
1925 // Check if this direct call is to an Intrinsic (starts with "llvm.")
1926 static Ice::IceString LLVMPrefix("llvm.");
1927 Ice::IceString Name = Fcn->getName();
1928 if (isStringPrefix(Name, LLVMPrefix)) {
1929 Ice::IceString Suffix = Name.substr(LLVMPrefix.size());
1930 IntrinsicInfo =
1931 getTranslator().getContext()->getIntrinsicsInfo().find(Suffix);
1932 if (!IntrinsicInfo) {
1933 std::string Buffer;
1934 raw_string_ostream StrBuf(Buffer);
1935 StrBuf << "Invalid PNaCl intrinsic call to " << Name;
1936 Error(StrBuf.str());
1937 return;
1938 }
1939 }
1940 } else {
1941 ReturnType = Context->convertToIceType(Context->getTypeByID(Values[2]));
1942 }
1943
1944 // Create the call instruction.
1945 Ice::Variable *Dest =
1946 (ReturnType == Ice::IceType_void) ? NULL : getNextInstVar(ReturnType);
1947 Ice::SizeT NumParams = Values.size() - ParamsStartIndex;
1948 Ice::InstCall *Inst = NULL;
1949 if (IntrinsicInfo) {
1950 Inst =
1951 Ice::InstIntrinsicCall::create(Func, NumParams, Dest, Callee,
1952 IntrinsicInfo->Info);
1953 } else {
1954 Inst = Ice::InstCall::create(Func, NumParams, Dest, Callee, IsTailCall);
1955 }
1956
1957 // Add parameters.
1958 for (Ice::SizeT ParamIndex = 0; ParamIndex < NumParams; ++ParamIndex) {
1959 Inst->addArg(
1960 getRelativeOperand(Values[ParamsStartIndex + ParamIndex], BaseIndex));
1961 }
1962
1963 // If intrinsic call, validate call signature.
1964 if (IntrinsicInfo) {
1965 Ice::SizeT ArgIndex = 0;
1966 switch (IntrinsicInfo->validateCall(Inst, ArgIndex)) {
1967 default:
1968 Error("Unknown validation error for intrinsic call");
1969 // TODO(kschimpf) Remove error recovery once implementation complete.
1970 break;
1971 case Ice::Intrinsics::IsValidCall:
1972 break;
1973 case Ice::Intrinsics::BadReturnType: {
1974 std::string Buffer;
1975 raw_string_ostream StrBuf(Buffer);
1976 StrBuf << "Intrinsic call expects return type "
1977 << IntrinsicInfo->getReturnType()
1978 << ". Found: " << Inst->getReturnType();
1979 Error(StrBuf.str());
1980 // TODO(kschimpf) Remove error recovery once implementation complete.
1981 break;
1982 }
1983 case Ice::Intrinsics::WrongNumOfArgs: {
1984 std::string Buffer;
1985 raw_string_ostream StrBuf(Buffer);
1986 StrBuf << "Intrinsic call expects " << IntrinsicInfo->getNumArgs()
1987 << ". Found: " << Inst->getNumArgs();
1988 Error(StrBuf.str());
1989 // TODO(kschimpf) Remove error recovery once implementation complete.
1990 break;
1991 }
1992 case Ice::Intrinsics::WrongCallArgType: {
1993 std::string Buffer;
1994 raw_string_ostream StrBuf(Buffer);
1995 StrBuf << "Intrinsic call argument " << ArgIndex << " expects type "
1996 << IntrinsicInfo->getArgType(ArgIndex)
1997 << ". Found: " << Inst->getArg(ArgIndex)->getType();
1998 Error(StrBuf.str());
1999 // TODO(kschimpf) Remove error recovery once implementation complete.
2000 break;
2001 }
2002 }
2003 }
2004
2005 CurrentNode->appendInst(Inst);
2006 return;
2007 }
1837 case naclbitc::FUNC_CODE_INST_FORWARDTYPEREF: { 2008 case naclbitc::FUNC_CODE_INST_FORWARDTYPEREF: {
1838 // FORWARDTYPEREF: [opval, ty] 2009 // FORWARDTYPEREF: [opval, ty]
1839 if (!isValidRecordSize(2, "function block forward type ref")) 2010 if (!isValidRecordSize(2, "function block forward type ref"))
1840 return; 2011 return;
1841 setOperand(Values[0], createInstVar(Context->convertToIceType( 2012 setOperand(Values[0], createInstVar(Context->convertToIceType(
1842 Context->getTypeByID(Values[1])))); 2013 Context->getTypeByID(Values[1]))));
1843 break; 2014 break;
1844 } 2015 }
1845 case naclbitc::FUNC_CODE_INST_CALL:
1846 case naclbitc::FUNC_CODE_INST_CALL_INDIRECT:
1847 default: 2016 default:
1848 // Generate error message! 2017 // Generate error message!
1849 BlockParserBaseClass::ProcessRecord(); 2018 BlockParserBaseClass::ProcessRecord();
1850 break; 2019 break;
1851 } 2020 }
1852 } 2021 }
1853 2022
1854 /// Parses constants within a function block. 2023 /// Parses constants within a function block.
1855 class ConstantsParser : public BlockParserBaseClass { 2024 class ConstantsParser : public BlockParserBaseClass {
1856 ConstantsParser(const ConstantsParser &) LLVM_DELETED_FUNCTION; 2025 ConstantsParser(const ConstantsParser &) LLVM_DELETED_FUNCTION;
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after
2243 2412
2244 if (TopLevelBlocks != 1) { 2413 if (TopLevelBlocks != 1) {
2245 errs() << IRFilename 2414 errs() << IRFilename
2246 << ": Contains more than one module. Found: " << TopLevelBlocks 2415 << ": Contains more than one module. Found: " << TopLevelBlocks
2247 << "\n"; 2416 << "\n";
2248 ErrorStatus = true; 2417 ErrorStatus = true;
2249 } 2418 }
2250 } 2419 }
2251 2420
2252 } // end of namespace Ice 2421 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceTargetLoweringX8632.h ('k') | tests_lit/reader_tests/call.ll » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698