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

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

Powered by Google App Engine
This is Rietveld 408576698