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 |
11 // translator. | 11 // translator. |
12 // | 12 // |
13 //===----------------------------------------------------------------------===// | 13 //===----------------------------------------------------------------------===// |
14 | 14 |
15 #include "llvm/Analysis/NaCl/PNaClABIProps.h" | 15 #include "llvm/Analysis/NaCl/PNaClABIProps.h" |
16 #include "llvm/Bitcode/NaCl/NaClBitcodeDecoders.h" | 16 #include "llvm/Bitcode/NaCl/NaClBitcodeDecoders.h" |
17 #include "llvm/Bitcode/NaCl/NaClBitcodeHeader.h" | 17 #include "llvm/Bitcode/NaCl/NaClBitcodeHeader.h" |
18 #include "llvm/Bitcode/NaCl/NaClBitcodeParser.h" | 18 #include "llvm/Bitcode/NaCl/NaClBitcodeParser.h" |
19 #include "llvm/Bitcode/NaCl/NaClReaderWriter.h" | 19 #include "llvm/Bitcode/NaCl/NaClReaderWriter.h" |
20 #include "llvm/IR/Constants.h" | 20 #include "llvm/IR/Constants.h" |
21 #include "llvm/IR/DataLayout.h" | 21 #include "llvm/IR/DataLayout.h" |
22 #include "llvm/IR/LLVMContext.h" | 22 #include "llvm/IR/LLVMContext.h" |
23 #include "llvm/IR/Module.h" | 23 #include "llvm/IR/Module.h" |
24 #include "llvm/Support/Format.h" | 24 #include "llvm/Support/Format.h" |
25 #include "llvm/Support/MemoryBuffer.h" | 25 #include "llvm/Support/MemoryBuffer.h" |
26 #include "llvm/Support/raw_ostream.h" | 26 #include "llvm/Support/raw_ostream.h" |
27 #include "llvm/Support/ValueHandle.h" | |
28 | 27 |
29 #include "IceCfg.h" | 28 #include "IceCfg.h" |
30 #include "IceCfgNode.h" | 29 #include "IceCfgNode.h" |
31 #include "IceClFlags.h" | 30 #include "IceClFlags.h" |
32 #include "IceDefs.h" | 31 #include "IceDefs.h" |
33 #include "IceGlobalInits.h" | 32 #include "IceGlobalInits.h" |
34 #include "IceInst.h" | 33 #include "IceInst.h" |
35 #include "IceOperand.h" | 34 #include "IceOperand.h" |
36 #include "IceTypeConverter.h" | 35 #include "IceTypeConverter.h" |
37 #include "PNaClTranslator.h" | 36 #include "PNaClTranslator.h" |
38 | 37 |
| 38 namespace { |
39 using namespace llvm; | 39 using namespace llvm; |
40 | 40 |
41 namespace { | |
42 | |
43 // TODO(kschimpf) Remove error recovery once implementation complete. | 41 // TODO(kschimpf) Remove error recovery once implementation complete. |
44 static cl::opt<bool> AllowErrorRecovery( | 42 static cl::opt<bool> AllowErrorRecovery( |
45 "allow-pnacl-reader-error-recovery", | 43 "allow-pnacl-reader-error-recovery", |
46 cl::desc("Allow error recovery when reading PNaCl bitcode."), | 44 cl::desc("Allow error recovery when reading PNaCl bitcode."), |
47 cl::init(false)); | 45 cl::init(false)); |
48 | 46 |
49 // Models elements in the list of types defined in the types block. | 47 // Models elements in the list of types defined in the types block. |
50 // These elements can be undefined, a (simple) type, or a function type | 48 // These elements can be undefined, a (simple) type, or a function type |
51 // signature. Note that an extended type is undefined on construction. | 49 // signature. Note that an extended type is undefined on construction. |
52 // Use methods setAsSimpleType and setAsFuncSigType to define | 50 // Use methods setAsSimpleType and setAsFuncSigType to define |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 break; | 151 break; |
154 } | 152 } |
155 } | 153 } |
156 | 154 |
157 // Top-level class to read PNaCl bitcode files, and translate to ICE. | 155 // Top-level class to read PNaCl bitcode files, and translate to ICE. |
158 class TopLevelParser : public NaClBitcodeParser { | 156 class TopLevelParser : public NaClBitcodeParser { |
159 TopLevelParser(const TopLevelParser &) = delete; | 157 TopLevelParser(const TopLevelParser &) = delete; |
160 TopLevelParser &operator=(const TopLevelParser &) = delete; | 158 TopLevelParser &operator=(const TopLevelParser &) = delete; |
161 | 159 |
162 public: | 160 public: |
| 161 typedef std::vector<Ice::FunctionDeclaration *> FunctionDeclarationListType; |
| 162 |
163 TopLevelParser(Ice::Translator &Translator, const std::string &InputName, | 163 TopLevelParser(Ice::Translator &Translator, const std::string &InputName, |
164 NaClBitcodeHeader &Header, NaClBitstreamCursor &Cursor, | 164 NaClBitcodeHeader &Header, NaClBitstreamCursor &Cursor, |
165 bool &ErrorStatus) | 165 bool &ErrorStatus) |
166 : NaClBitcodeParser(Cursor), Translator(Translator), | 166 : NaClBitcodeParser(Cursor), Translator(Translator), |
167 Mod(new Module(InputName, getGlobalContext())), DL(PNaClDataLayout), | 167 Mod(new Module(InputName, getGlobalContext())), DL(PNaClDataLayout), |
168 Header(Header), TypeConverter(getLLVMContext()), | 168 Header(Header), TypeConverter(Mod->getContext()), |
169 ErrorStatus(ErrorStatus), NumErrors(0), NumFunctionIds(0), | 169 ErrorStatus(ErrorStatus), NumErrors(0), NumFunctionIds(0), |
170 NumFunctionBlocks(0) { | 170 NumFunctionBlocks(0) { |
171 Mod->setDataLayout(PNaClDataLayout); | 171 Mod->setDataLayout(PNaClDataLayout); |
172 setErrStream(Translator.getContext()->getStrDump()); | 172 setErrStream(Translator.getContext()->getStrDump()); |
173 } | 173 } |
174 | 174 |
175 ~TopLevelParser() override { DeleteContainerPointers(GlobalIDAddresses); } | 175 ~TopLevelParser() override {} |
176 | 176 |
177 Ice::Translator &getTranslator() { return Translator; } | 177 Ice::Translator &getTranslator() { return Translator; } |
178 | 178 |
179 // Generates error with given Message. Always returns true. | 179 // Generates error with given Message. Always returns true. |
180 bool Error(const std::string &Message) override { | 180 bool Error(const std::string &Message) override { |
181 ErrorStatus = true; | 181 ErrorStatus = true; |
182 ++NumErrors; | 182 ++NumErrors; |
183 NaClBitcodeParser::Error(Message); | 183 NaClBitcodeParser::Error(Message); |
184 if (!AllowErrorRecovery) | 184 if (!AllowErrorRecovery) |
185 report_fatal_error("Unable to continue"); | 185 report_fatal_error("Unable to continue"); |
186 return true; | 186 return true; |
187 } | 187 } |
188 | 188 |
189 /// Returns the number of errors found while parsing the bitcode | 189 /// Returns the number of errors found while parsing the bitcode |
190 /// file. | 190 /// file. |
191 unsigned getNumErrors() const { return NumErrors; } | 191 unsigned getNumErrors() const { return NumErrors; } |
192 | 192 |
193 /// Returns the LLVM module associated with the translation. | 193 /// Returns the LLVM module associated with the translation. |
194 Module *getModule() const { return Mod.get(); } | 194 Module *getModule() const { return Mod.get(); } |
195 | 195 |
196 const DataLayout &getDataLayout() const { return DL; } | 196 const DataLayout &getDataLayout() const { return DL; } |
197 | 197 |
198 /// Returns the number of bytes in the bitcode header. | 198 /// Returns the number of bytes in the bitcode header. |
199 size_t getHeaderSize() const { return Header.getHeaderSize(); } | 199 size_t getHeaderSize() const { return Header.getHeaderSize(); } |
200 | 200 |
201 /// Returns the llvm context to use. | |
202 LLVMContext &getLLVMContext() const { return Mod->getContext(); } | |
203 | |
204 /// Changes the size of the type list to the given size. | 201 /// Changes the size of the type list to the given size. |
205 void resizeTypeIDValues(unsigned NewSize) { TypeIDValues.resize(NewSize); } | 202 void resizeTypeIDValues(unsigned NewSize) { TypeIDValues.resize(NewSize); } |
206 | 203 |
207 /// Returns the undefined type associated with type ID. | 204 /// Returns the undefined type associated with type ID. |
208 /// Note: Returns extended type ready to be defined. | 205 /// Note: Returns extended type ready to be defined. |
209 ExtendedType *getTypeByIDForDefining(unsigned ID) { | 206 ExtendedType *getTypeByIDForDefining(unsigned ID) { |
210 // Get corresponding element, verifying the value is still undefined | 207 // Get corresponding element, verifying the value is still undefined |
211 // (and hence allowed to be defined). | 208 // (and hence allowed to be defined). |
212 ExtendedType *Ty = getTypeByIDAsKind(ID, ExtendedType::Undefined); | 209 ExtendedType *Ty = getTypeByIDAsKind(ID, ExtendedType::Undefined); |
213 if (Ty) | 210 if (Ty) |
(...skipping 15 matching lines...) Expand all Loading... |
229 /// Returns the type signature associated with the given index. | 226 /// Returns the type signature associated with the given index. |
230 const Ice::FuncSigType &getFuncSigTypeByID(unsigned ID) { | 227 const Ice::FuncSigType &getFuncSigTypeByID(unsigned ID) { |
231 const ExtendedType *Ty = getTypeByIDAsKind(ID, ExtendedType::FuncSig); | 228 const ExtendedType *Ty = getTypeByIDAsKind(ID, ExtendedType::FuncSig); |
232 if (Ty == nullptr) | 229 if (Ty == nullptr) |
233 // Return error recovery value. | 230 // Return error recovery value. |
234 return UndefinedFuncSigType; | 231 return UndefinedFuncSigType; |
235 return cast<FuncSigExtendedType>(Ty)->getSignature(); | 232 return cast<FuncSigExtendedType>(Ty)->getSignature(); |
236 } | 233 } |
237 | 234 |
238 /// Sets the next function ID to the given LLVM function. | 235 /// Sets the next function ID to the given LLVM function. |
239 void setNextFunctionID(Function *Fcn) { | 236 void setNextFunctionID(Ice::FunctionDeclaration *Fcn) { |
240 ++NumFunctionIds; | 237 ++NumFunctionIds; |
241 FunctionIDValues.push_back(Fcn); | 238 FunctionDeclarationList.push_back(Fcn); |
242 } | 239 } |
243 | 240 |
244 /// Defines the next function ID as one that has an implementation | 241 /// Defines the next function ID as one that has an implementation |
245 /// (i.e a corresponding function block in the bitcode). | 242 /// (i.e a corresponding function block in the bitcode). |
246 void setNextValueIDAsImplementedFunction() { | 243 void setNextValueIDAsImplementedFunction() { |
247 DefiningFunctionsList.push_back(FunctionIDValues.size()); | 244 DefiningFunctionDeclarationsList.push_back(FunctionDeclarationList.size()); |
248 } | 245 } |
249 | 246 |
250 /// Returns the value id that should be associated with the the | 247 /// Returns the value id that should be associated with the the |
251 /// current function block. Increments internal counters during call | 248 /// current function block. Increments internal counters during call |
252 /// so that it will be in correct position for next function block. | 249 /// so that it will be in correct position for next function block. |
253 unsigned getNextFunctionBlockValueID() { | 250 unsigned getNextFunctionBlockValueID() { |
254 if (NumFunctionBlocks >= DefiningFunctionsList.size()) | 251 if (NumFunctionBlocks >= DefiningFunctionDeclarationsList.size()) |
255 report_fatal_error( | 252 report_fatal_error( |
256 "More function blocks than defined function addresses"); | 253 "More function blocks than defined function addresses"); |
257 return DefiningFunctionsList[NumFunctionBlocks++]; | 254 return DefiningFunctionDeclarationsList[NumFunctionBlocks++]; |
258 } | 255 } |
259 | 256 |
260 /// Returns the LLVM Function address associated with ID. | 257 /// Returns the function associated with ID. |
261 Function *getFunctionByID(unsigned ID) const { | 258 Ice::FunctionDeclaration *getFunctionByID(unsigned ID) { |
262 if (ID >= FunctionIDValues.size()) | 259 if (ID < FunctionDeclarationList.size()) |
263 return nullptr; | 260 return FunctionDeclarationList[ID]; |
264 Value *V = FunctionIDValues[ID]; | 261 return reportGetFunctionByIDError(ID); |
265 return cast<Function>(V); | |
266 } | 262 } |
267 | 263 |
268 /// Returns the corresponding constant associated with a global value | 264 /// Returns the list of function declarations. |
| 265 const FunctionDeclarationListType &getFunctionDeclarationList() const { |
| 266 return FunctionDeclarationList; |
| 267 } |
| 268 |
| 269 /// Returns the corresponding constant associated with a global declaration. |
269 /// (i.e. relocatable). | 270 /// (i.e. relocatable). |
270 Ice::Constant *getOrCreateGlobalConstantByID(unsigned ID) { | 271 Ice::Constant *getOrCreateGlobalConstantByID(unsigned ID) { |
271 // TODO(kschimpf): Can this be built when creating global initializers? | 272 // TODO(kschimpf): Can this be built when creating global initializers? |
272 Ice::Constant *C; | 273 Ice::Constant *C; |
273 if (ID >= ValueIDConstants.size()) { | 274 if (ID >= ValueIDConstants.size()) { |
274 C = nullptr; | 275 C = nullptr; |
275 unsigned ExpectedSize = | 276 unsigned ExpectedSize = |
276 FunctionIDValues.size() + GlobalIDAddresses.size(); | 277 FunctionDeclarationList.size() + VariableDeclarations.size(); |
277 if (ID >= ExpectedSize) | 278 if (ID >= ExpectedSize) |
278 ExpectedSize = ID; | 279 ExpectedSize = ID; |
279 ValueIDConstants.resize(ExpectedSize); | 280 ValueIDConstants.resize(ExpectedSize); |
280 } else { | 281 } else { |
281 C = ValueIDConstants[ID]; | 282 C = ValueIDConstants[ID]; |
282 } | 283 } |
283 if (C != nullptr) | 284 if (C != nullptr) |
284 return C; | 285 return C; |
285 | 286 |
286 // If reached, no such constant exists, create one. | 287 // If reached, no such constant exists, create one. |
| 288 // TODO(kschimpf) Don't get addresses of intrinsic function declarations. |
287 std::string Name; | 289 std::string Name; |
288 unsigned FcnIDSize = FunctionIDValues.size(); | 290 unsigned FcnIDSize = FunctionDeclarationList.size(); |
289 if (ID < FcnIDSize) { | 291 if (ID < FcnIDSize) { |
290 Name = FunctionIDValues[ID]->getName(); | 292 Name = FunctionDeclarationList[ID]->getName(); |
291 } else if ((ID - FcnIDSize) < GlobalIDAddresses.size()) { | 293 } else if ((ID - FcnIDSize) < VariableDeclarations.size()) { |
292 Name = GlobalIDAddresses[ID - FcnIDSize]->getName(); | 294 Name = VariableDeclarations[ID - FcnIDSize]->getName(); |
293 } else { | 295 } else { |
294 std::string Buffer; | 296 std::string Buffer; |
295 raw_string_ostream StrBuf(Buffer); | 297 raw_string_ostream StrBuf(Buffer); |
296 StrBuf << "Reference to global not defined: " << ID; | 298 StrBuf << "Reference to global not defined: " << ID; |
297 Error(StrBuf.str()); | 299 Error(StrBuf.str()); |
298 Name = "??"; | 300 Name = "??"; |
299 } | 301 } |
300 const uint64_t Offset = 0; | 302 const uint64_t Offset = 0; |
301 C = getTranslator().getContext()->getConstantSym( | 303 C = getTranslator().getContext()->getConstantSym( |
302 getIcePointerType(), Offset, Name); | 304 getIcePointerType(), Offset, Name); |
303 ValueIDConstants[ID] = C; | 305 ValueIDConstants[ID] = C; |
304 return C; | 306 return C; |
305 } | 307 } |
306 | 308 |
307 /// Returns the number of function addresses (i.e. ID's) defined in | 309 /// Returns the number of function declarations in the bitcode file. |
308 /// the bitcode file. | |
309 unsigned getNumFunctionIDs() const { return NumFunctionIds; } | 310 unsigned getNumFunctionIDs() const { return NumFunctionIds; } |
310 | 311 |
311 /// Returns the number of global IDs (function and global addresses) | 312 /// Returns the number of global declarations (i.e. IDs) defined in |
312 /// defined in the bitcode file. | 313 /// the bitcode file. |
313 unsigned getNumGlobalIDs() const { | 314 unsigned getNumGlobalIDs() const { |
314 return FunctionIDValues.size() + GlobalIDAddresses.size(); | 315 return FunctionDeclarationList.size() + VariableDeclarations.size(); |
315 } | 316 } |
316 | 317 |
317 /// Creates Count global addresses. | 318 /// Creates Count global variable declarations. |
318 void CreateGlobalAddresses(size_t Count) { | 319 void CreateGlobalVariables(size_t Count) { |
319 assert(GlobalIDAddresses.empty()); | 320 assert(VariableDeclarations.empty()); |
| 321 Ice::GlobalContext *Context = getTranslator().getContext(); |
320 for (size_t i = 0; i < Count; ++i) { | 322 for (size_t i = 0; i < Count; ++i) { |
321 GlobalIDAddresses.push_back(new Ice::GlobalAddress()); | 323 VariableDeclarations.push_back(Ice::VariableDeclaration::create(Context)); |
322 } | 324 } |
323 } | 325 } |
324 | 326 |
325 /// Returns the number of global addresses (i.e. ID's) defined in | 327 /// Returns the number of global variable declarations in the |
326 /// the bitcode file. | 328 /// bitcode file. |
327 Ice::SizeT getNumGlobalAddresses() const { return GlobalIDAddresses.size(); } | 329 Ice::SizeT getNumGlobalVariables() const { |
328 | 330 return VariableDeclarations.size(); |
329 /// Returns the global address with the given index. | |
330 Ice::GlobalAddress *getGlobalAddress(size_t Index) { | |
331 if (Index < GlobalIDAddresses.size()) | |
332 return GlobalIDAddresses[Index]; | |
333 std::string Buffer; | |
334 raw_string_ostream StrBuf(Buffer); | |
335 StrBuf << "Global index " << Index | |
336 << " not allowed. Out of range. Must be less than " | |
337 << GlobalIDAddresses.size(); | |
338 Error(StrBuf.str()); | |
339 // TODO(kschimpf) Remove error recovery once implementation complete. | |
340 if (!GlobalIDAddresses.empty()) | |
341 return GlobalIDAddresses[0]; | |
342 report_fatal_error("Unable to continue"); | |
343 } | 331 } |
344 | 332 |
345 /// Returns the list of read global addresses. | 333 /// Returns the global variable declaration with the given index. |
346 const Ice::Translator::GlobalAddressList &getGlobalIDAddresses() { | 334 Ice::VariableDeclaration *getGlobalVariableByID(unsigned Index) { |
347 return GlobalIDAddresses; | 335 if (Index < VariableDeclarations.size()) |
| 336 return VariableDeclarations[Index]; |
| 337 return reportGetGlobalVariableByIDError(Index); |
| 338 } |
| 339 |
| 340 /// Returns the global declaration (variable or function) with the |
| 341 /// given Index. |
| 342 Ice::GlobalDeclaration *getGlobalDeclarationByID(size_t Index) { |
| 343 if (Index < NumFunctionIds) |
| 344 return getFunctionByID(Index); |
| 345 else |
| 346 return getGlobalVariableByID(Index - NumFunctionIds); |
| 347 } |
| 348 |
| 349 /// Returns the list of parsed global variable declarations. |
| 350 const Ice::Translator::VariableDeclarationListType &getGlobalVariables() { |
| 351 return VariableDeclarations; |
348 } | 352 } |
349 | 353 |
350 /// Returns the corresponding ICE type for LLVMTy. | 354 /// Returns the corresponding ICE type for LLVMTy. |
351 Ice::Type convertToIceType(Type *LLVMTy) { | 355 Ice::Type convertToIceType(Type *LLVMTy) { |
352 Ice::Type IceTy = TypeConverter.convertToIceType(LLVMTy); | 356 Ice::Type IceTy = TypeConverter.convertToIceType(LLVMTy); |
353 if (IceTy >= Ice::IceType_NUM) { | 357 if (IceTy >= Ice::IceType_NUM) { |
354 return convertToIceTypeError(LLVMTy); | 358 return convertToIceTypeError(LLVMTy); |
355 } | 359 } |
356 return IceTy; | 360 return IceTy; |
357 } | 361 } |
(...skipping 18 matching lines...) Expand all Loading... |
376 // The bitcode header. | 380 // The bitcode header. |
377 NaClBitcodeHeader &Header; | 381 NaClBitcodeHeader &Header; |
378 // Converter between LLVM and ICE types. | 382 // Converter between LLVM and ICE types. |
379 Ice::TypeConverter TypeConverter; | 383 Ice::TypeConverter TypeConverter; |
380 // The exit status that should be set to true if an error occurs. | 384 // The exit status that should be set to true if an error occurs. |
381 bool &ErrorStatus; | 385 bool &ErrorStatus; |
382 // The number of errors reported. | 386 // The number of errors reported. |
383 unsigned NumErrors; | 387 unsigned NumErrors; |
384 // The types associated with each type ID. | 388 // The types associated with each type ID. |
385 std::vector<ExtendedType> TypeIDValues; | 389 std::vector<ExtendedType> TypeIDValues; |
386 // The set of function value IDs. | 390 // The set of functions. |
387 std::vector<WeakVH> FunctionIDValues; | 391 FunctionDeclarationListType FunctionDeclarationList; |
388 // The set of global addresses IDs. | 392 // The set of global variables. |
389 Ice::Translator::GlobalAddressList GlobalIDAddresses; | 393 Ice::Translator::VariableDeclarationListType VariableDeclarations; |
390 // Relocatable constants associated with FunctionIDValues and | 394 // Relocatable constants associated with global declarations. |
391 // GlobalIDAddresses. | |
392 std::vector<Ice::Constant *> ValueIDConstants; | 395 std::vector<Ice::Constant *> ValueIDConstants; |
393 // The number of function IDs. | 396 // The number of function declarations (i.e. IDs). |
394 unsigned NumFunctionIds; | 397 unsigned NumFunctionIds; |
395 // The number of function blocks (processed so far). | 398 // The number of function blocks (processed so far). |
396 unsigned NumFunctionBlocks; | 399 unsigned NumFunctionBlocks; |
397 // The list of value IDs (in the order found) of defining function | 400 // The list of function declaration IDs (in the order found) that |
398 // addresses. | 401 // aren't just proto declarations. |
399 std::vector<unsigned> DefiningFunctionsList; | 402 // TODO(kschimpf): Instead of using this list, just use |
| 403 // FunctionDeclarationList, and the isProto member function. |
| 404 std::vector<unsigned> DefiningFunctionDeclarationsList; |
400 // Error recovery value to use when getFuncSigTypeByID fails. | 405 // Error recovery value to use when getFuncSigTypeByID fails. |
401 Ice::FuncSigType UndefinedFuncSigType; | 406 Ice::FuncSigType UndefinedFuncSigType; |
402 | 407 |
403 bool ParseBlock(unsigned BlockID) override; | 408 bool ParseBlock(unsigned BlockID) override; |
404 | 409 |
405 // Gets extended type associated with the given index, assuming the | 410 // Gets extended type associated with the given index, assuming the |
406 // extended type is of the WantedKind. Generates error message if | 411 // extended type is of the WantedKind. Generates error message if |
407 // corresponding extended type of WantedKind can't be found, and | 412 // corresponding extended type of WantedKind can't be found, and |
408 // returns nullptr. | 413 // returns nullptr. |
409 ExtendedType *getTypeByIDAsKind(unsigned ID, | 414 ExtendedType *getTypeByIDAsKind(unsigned ID, |
410 ExtendedType::TypeKind WantedKind) { | 415 ExtendedType::TypeKind WantedKind) { |
411 ExtendedType *Ty = nullptr; | 416 ExtendedType *Ty = nullptr; |
412 if (ID < TypeIDValues.size()) { | 417 if (ID < TypeIDValues.size()) { |
413 Ty = &TypeIDValues[ID]; | 418 Ty = &TypeIDValues[ID]; |
414 if (Ty->getKind() == WantedKind) | 419 if (Ty->getKind() == WantedKind) |
415 return Ty; | 420 return Ty; |
416 } | 421 } |
417 // Generate an error message and set ErrorStatus. | 422 // Generate an error message and set ErrorStatus. |
418 this->reportBadTypeIDAs(ID, Ty, WantedKind); | 423 this->reportBadTypeIDAs(ID, Ty, WantedKind); |
419 return nullptr; | 424 return nullptr; |
420 } | 425 } |
421 | 426 |
422 // Reports that type ID is undefined, or not of the WantedType. | 427 // Reports that type ID is undefined, or not of the WantedType. |
423 void reportBadTypeIDAs(unsigned ID, const ExtendedType *Ty, | 428 void reportBadTypeIDAs(unsigned ID, const ExtendedType *Ty, |
424 ExtendedType::TypeKind WantedType); | 429 ExtendedType::TypeKind WantedType); |
425 | 430 |
| 431 // Reports that there is no function declaration for ID. Returns an |
| 432 // error recovery value to use. |
| 433 Ice::FunctionDeclaration *reportGetFunctionByIDError(unsigned ID); |
| 434 |
| 435 // Reports that there is not global variable declaration for |
| 436 // ID. Returns an error recovery value to use. |
| 437 Ice::VariableDeclaration *reportGetGlobalVariableByIDError(unsigned Index); |
| 438 |
426 // Reports that there is no corresponding ICE type for LLVMTy, and | 439 // Reports that there is no corresponding ICE type for LLVMTy, and |
427 // returns ICE::IceType_void. | 440 // returns ICE::IceType_void. |
428 Ice::Type convertToIceTypeError(Type *LLVMTy); | 441 Ice::Type convertToIceTypeError(Type *LLVMTy); |
429 }; | 442 }; |
430 | 443 |
431 void TopLevelParser::reportBadTypeIDAs(unsigned ID, const ExtendedType *Ty, | 444 void TopLevelParser::reportBadTypeIDAs(unsigned ID, const ExtendedType *Ty, |
432 ExtendedType::TypeKind WantedType) { | 445 ExtendedType::TypeKind WantedType) { |
433 std::string Buffer; | 446 std::string Buffer; |
434 raw_string_ostream StrBuf(Buffer); | 447 raw_string_ostream StrBuf(Buffer); |
435 if (Ty == nullptr) { | 448 if (Ty == nullptr) { |
436 StrBuf << "Can't find extended type for type id: " << ID; | 449 StrBuf << "Can't find extended type for type id: " << ID; |
437 } else { | 450 } else { |
438 StrBuf << "Type id " << ID << " not " << WantedType << ". Found: " << *Ty; | 451 StrBuf << "Type id " << ID << " not " << WantedType << ". Found: " << *Ty; |
439 } | 452 } |
440 Error(StrBuf.str()); | 453 Error(StrBuf.str()); |
441 } | 454 } |
442 | 455 |
| 456 Ice::FunctionDeclaration * |
| 457 TopLevelParser::reportGetFunctionByIDError(unsigned ID) { |
| 458 std::string Buffer; |
| 459 raw_string_ostream StrBuf(Buffer); |
| 460 StrBuf << "Function index " << ID |
| 461 << " not allowed. Out of range. Must be less than " |
| 462 << FunctionDeclarationList.size(); |
| 463 Error(StrBuf.str()); |
| 464 // TODO(kschimpf) Remove error recovery once implementation complete. |
| 465 if (!FunctionDeclarationList.empty()) |
| 466 return FunctionDeclarationList[0]; |
| 467 report_fatal_error("Unable to continue"); |
| 468 } |
| 469 |
| 470 Ice::VariableDeclaration * |
| 471 TopLevelParser::reportGetGlobalVariableByIDError(unsigned Index) { |
| 472 std::string Buffer; |
| 473 raw_string_ostream StrBuf(Buffer); |
| 474 StrBuf << "Global index " << Index |
| 475 << " not allowed. Out of range. Must be less than " |
| 476 << VariableDeclarations.size(); |
| 477 Error(StrBuf.str()); |
| 478 // TODO(kschimpf) Remove error recovery once implementation complete. |
| 479 if (!VariableDeclarations.empty()) |
| 480 return VariableDeclarations[0]; |
| 481 report_fatal_error("Unable to continue"); |
| 482 } |
| 483 |
443 Ice::Type TopLevelParser::convertToIceTypeError(Type *LLVMTy) { | 484 Ice::Type TopLevelParser::convertToIceTypeError(Type *LLVMTy) { |
444 std::string Buffer; | 485 std::string Buffer; |
445 raw_string_ostream StrBuf(Buffer); | 486 raw_string_ostream StrBuf(Buffer); |
446 StrBuf << "Invalid LLVM type: " << *LLVMTy; | 487 StrBuf << "Invalid LLVM type: " << *LLVMTy; |
447 Error(StrBuf.str()); | 488 Error(StrBuf.str()); |
448 return Ice::IceType_void; | 489 return Ice::IceType_void; |
449 } | 490 } |
450 | 491 |
451 // Base class for parsing blocks within the bitcode file. Note: | 492 // Base class for parsing blocks within the bitcode file. Note: |
452 // Because this is the base class of block parsers, we generate error | 493 // Because this is the base class of block parsers, we generate error |
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
740 } | 781 } |
741 return; | 782 return; |
742 } | 783 } |
743 default: | 784 default: |
744 BlockParserBaseClass::ProcessRecord(); | 785 BlockParserBaseClass::ProcessRecord(); |
745 return; | 786 return; |
746 } | 787 } |
747 llvm_unreachable("Unknown type block record not processed!"); | 788 llvm_unreachable("Unknown type block record not processed!"); |
748 } | 789 } |
749 | 790 |
750 /// Parses the globals block (i.e. global variables). | 791 /// Parses the globals block (i.e. global variable declarations and |
| 792 /// corresponding initializers). |
751 class GlobalsParser : public BlockParserBaseClass { | 793 class GlobalsParser : public BlockParserBaseClass { |
752 public: | 794 public: |
753 GlobalsParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) | 795 GlobalsParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) |
754 : BlockParserBaseClass(BlockID, EnclosingParser), InitializersNeeded(0), | 796 : BlockParserBaseClass(BlockID, EnclosingParser), InitializersNeeded(0), |
755 NextGlobalID(0), CurrentAddress(&DummyAddress) {} | 797 NextGlobalID(0), DummyGlobalVar(Ice::VariableDeclaration::create( |
756 | 798 getTranslator().getContext())), |
757 ~GlobalsParser() override {} | 799 CurGlobalVar(DummyGlobalVar) {} |
758 | 800 |
759 private: | 801 private: |
760 // Keeps track of how many initializers are expected for the global variable | 802 // Keeps track of how many initializers are expected for the global variable |
761 // being built. | 803 // declaration being built. |
762 unsigned InitializersNeeded; | 804 unsigned InitializersNeeded; |
763 | 805 |
764 // The index of the next global variable. | 806 // The index of the next global variable declaration. |
765 unsigned NextGlobalID; | 807 unsigned NextGlobalID; |
766 | 808 |
767 // Holds the current global address whose initializer is being defined. | 809 // Dummy global variable declaration to guarantee CurGlobalVar is |
768 Ice::GlobalAddress *CurrentAddress; | 810 // always defined (allowing code to not need to check if |
| 811 // CurGlobalVar is nullptr). |
| 812 Ice::VariableDeclaration *DummyGlobalVar; |
769 | 813 |
770 // Dummy global address to guarantee CurrentAddress is always defined | 814 // Holds the current global variable declaration being built. |
771 // (allowing code to not need to check if CurrentAddress is nullptr). | 815 Ice::VariableDeclaration *CurGlobalVar; |
772 Ice::GlobalAddress DummyAddress; | |
773 | 816 |
774 void ExitBlock() override { | 817 void ExitBlock() override { |
775 verifyNoMissingInitializers(); | 818 verifyNoMissingInitializers(); |
776 unsigned NumIDs = Context->getNumGlobalAddresses(); | 819 unsigned NumIDs = Context->getNumGlobalVariables(); |
777 if (NextGlobalID < NumIDs) { | 820 if (NextGlobalID < NumIDs) { |
778 std::string Buffer; | 821 std::string Buffer; |
779 raw_string_ostream StrBuf(Buffer); | 822 raw_string_ostream StrBuf(Buffer); |
780 StrBuf << "Globals block expects " << NumIDs | 823 StrBuf << "Globals block expects " << NumIDs |
781 << " global definitions. Found: " << NextGlobalID; | 824 << " global variable declarations. Found: " << NextGlobalID; |
782 Error(StrBuf.str()); | 825 Error(StrBuf.str()); |
783 } | 826 } |
784 BlockParserBaseClass::ExitBlock(); | 827 BlockParserBaseClass::ExitBlock(); |
785 } | 828 } |
786 | 829 |
787 void ProcessRecord() override; | 830 void ProcessRecord() override; |
788 | 831 |
789 // Checks if the number of initializers for the CurrentAddress is the same as | 832 // Checks if the number of initializers for the CurGlobalVar is the same as |
790 // the number found in the bitcode file. If different, and error message is | 833 // the number found in the bitcode file. If different, and error message is |
791 // generated, and the internal state of the parser is fixed so this condition | 834 // generated, and the internal state of the parser is fixed so this condition |
792 // is no longer violated. | 835 // is no longer violated. |
793 void verifyNoMissingInitializers() { | 836 void verifyNoMissingInitializers() { |
794 size_t NumInits = CurrentAddress->getInitializers().size(); | 837 size_t NumInits = CurGlobalVar->getInitializers().size(); |
795 if (InitializersNeeded != NumInits) { | 838 if (InitializersNeeded != NumInits) { |
796 std::string Buffer; | 839 std::string Buffer; |
797 raw_string_ostream StrBuf(Buffer); | 840 raw_string_ostream StrBuf(Buffer); |
798 StrBuf << "Global variable @g" << NextGlobalID << " expected " | 841 StrBuf << "Global variable @g" << NextGlobalID << " expected " |
799 << InitializersNeeded << " initializer"; | 842 << InitializersNeeded << " initializer"; |
800 if (InitializersNeeded > 1) | 843 if (InitializersNeeded > 1) |
801 StrBuf << "s"; | 844 StrBuf << "s"; |
802 StrBuf << ". Found: " << NumInits; | 845 StrBuf << ". Found: " << NumInits; |
803 Error(StrBuf.str()); | 846 Error(StrBuf.str()); |
| 847 InitializersNeeded = NumInits; |
804 } | 848 } |
805 } | 849 } |
806 }; | 850 }; |
807 | 851 |
808 void GlobalsParser::ProcessRecord() { | 852 void GlobalsParser::ProcessRecord() { |
809 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); | 853 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); |
810 switch (Record.GetCode()) { | 854 switch (Record.GetCode()) { |
811 case naclbitc::GLOBALVAR_COUNT: | 855 case naclbitc::GLOBALVAR_COUNT: |
812 // COUNT: [n] | 856 // COUNT: [n] |
813 if (!isValidRecordSize(1, "Globals count")) | 857 if (!isValidRecordSize(1, "Globals count")) |
814 return; | 858 return; |
815 if (NextGlobalID != Context->getNumGlobalAddresses()) { | 859 if (NextGlobalID != Context->getNumGlobalVariables()) { |
816 Error("Globals count record not first in block."); | 860 Error("Globals count record not first in block."); |
817 return; | 861 return; |
818 } | 862 } |
819 Context->CreateGlobalAddresses(Values[0]); | 863 Context->CreateGlobalVariables(Values[0]); |
820 return; | 864 return; |
821 case naclbitc::GLOBALVAR_VAR: { | 865 case naclbitc::GLOBALVAR_VAR: { |
822 // VAR: [align, isconst] | 866 // VAR: [align, isconst] |
823 if (!isValidRecordSize(2, "Globals variable")) | 867 if (!isValidRecordSize(2, "Globals variable")) |
824 return; | 868 return; |
825 verifyNoMissingInitializers(); | 869 verifyNoMissingInitializers(); |
826 InitializersNeeded = 1; | 870 InitializersNeeded = 1; |
827 CurrentAddress = Context->getGlobalAddress(NextGlobalID); | 871 CurGlobalVar = Context->getGlobalVariableByID(NextGlobalID); |
828 CurrentAddress->setAlignment((1 << Values[0]) >> 1); | 872 CurGlobalVar->setAlignment((1 << Values[0]) >> 1); |
829 CurrentAddress->setIsConstant(Values[1] != 0); | 873 CurGlobalVar->setIsConstant(Values[1] != 0); |
830 ++NextGlobalID; | 874 ++NextGlobalID; |
831 return; | 875 return; |
832 } | 876 } |
833 case naclbitc::GLOBALVAR_COMPOUND: | 877 case naclbitc::GLOBALVAR_COMPOUND: |
834 // COMPOUND: [size] | 878 // COMPOUND: [size] |
835 if (!isValidRecordSize(1, "globals compound")) | 879 if (!isValidRecordSize(1, "globals compound")) |
836 return; | 880 return; |
837 if (!CurrentAddress->getInitializers().empty()) { | 881 if (!CurGlobalVar->getInitializers().empty()) { |
838 Error("Globals compound record not first initializer"); | 882 Error("Globals compound record not first initializer"); |
839 return; | 883 return; |
840 } | 884 } |
841 if (Values[0] < 2) { | 885 if (Values[0] < 2) { |
842 std::string Buffer; | 886 std::string Buffer; |
843 raw_string_ostream StrBuf(Buffer); | 887 raw_string_ostream StrBuf(Buffer); |
844 StrBuf << "Globals compound record size invalid. Found: " << Values[0]; | 888 StrBuf << "Globals compound record size invalid. Found: " << Values[0]; |
845 Error(StrBuf.str()); | 889 Error(StrBuf.str()); |
846 return; | 890 return; |
847 } | 891 } |
848 InitializersNeeded = Values[0]; | 892 InitializersNeeded = Values[0]; |
849 return; | 893 return; |
850 case naclbitc::GLOBALVAR_ZEROFILL: { | 894 case naclbitc::GLOBALVAR_ZEROFILL: { |
851 // ZEROFILL: [size] | 895 // ZEROFILL: [size] |
852 if (!isValidRecordSize(1, "Globals zerofill")) | 896 if (!isValidRecordSize(1, "Globals zerofill")) |
853 return; | 897 return; |
854 CurrentAddress->addInitializer( | 898 CurGlobalVar->addInitializer( |
855 new Ice::GlobalAddress::ZeroInitializer(Values[0])); | 899 new Ice::VariableDeclaration::ZeroInitializer(Values[0])); |
856 break; | 900 return; |
857 } | 901 } |
858 case naclbitc::GLOBALVAR_DATA: { | 902 case naclbitc::GLOBALVAR_DATA: { |
859 // DATA: [b0, b1, ...] | 903 // DATA: [b0, b1, ...] |
860 if (!isValidRecordSizeAtLeast(1, "Globals data")) | 904 if (!isValidRecordSizeAtLeast(1, "Globals data")) |
861 return; | 905 return; |
862 CurrentAddress->addInitializer( | 906 CurGlobalVar->addInitializer( |
863 new Ice::GlobalAddress::DataInitializer(Values)); | 907 new Ice::VariableDeclaration::DataInitializer(Values)); |
864 break; | 908 return; |
865 } | 909 } |
866 case naclbitc::GLOBALVAR_RELOC: { | 910 case naclbitc::GLOBALVAR_RELOC: { |
867 // RELOC: [val, [addend]] | 911 // RELOC: [val, [addend]] |
868 if (!isValidRecordSizeInRange(1, 2, "Globals reloc")) | 912 if (!isValidRecordSizeInRange(1, 2, "Globals reloc")) |
869 return; | 913 return; |
870 unsigned Index = Values[0]; | 914 unsigned Index = Values[0]; |
871 Ice::SizeT Offset = 0; | 915 Ice::SizeT Offset = 0; |
872 if (Values.size() == 2) | 916 if (Values.size() == 2) |
873 Offset = Values[1]; | 917 Offset = Values[1]; |
874 unsigned NumFunctions = Context->getNumFunctionIDs(); | 918 CurGlobalVar->addInitializer(new Ice::VariableDeclaration::RelocInitializer( |
875 if (Index < NumFunctions) { | 919 Context->getGlobalDeclarationByID(Index), Offset)); |
876 llvm::Function *Fcn = Context->getFunctionByID(Index); | 920 return; |
877 Ice::GlobalAddress::RelocationAddress Addr(Fcn); | |
878 CurrentAddress->addInitializer( | |
879 new Ice::GlobalAddress::RelocInitializer(Addr, Offset)); | |
880 } else { | |
881 Ice::GlobalAddress::RelocationAddress Addr( | |
882 Context->getGlobalAddress(Index - NumFunctions)); | |
883 CurrentAddress->addInitializer( | |
884 new Ice::GlobalAddress::RelocInitializer(Addr, Offset)); | |
885 } | |
886 break; | |
887 } | 921 } |
888 default: | 922 default: |
889 BlockParserBaseClass::ProcessRecord(); | 923 BlockParserBaseClass::ProcessRecord(); |
890 return; | 924 return; |
891 } | 925 } |
892 } | 926 } |
893 | 927 |
894 /// Base class for parsing a valuesymtab block in the bitcode file. | 928 /// Base class for parsing a valuesymtab block in the bitcode file. |
895 class ValuesymtabParser : public BlockParserBaseClass { | 929 class ValuesymtabParser : public BlockParserBaseClass { |
896 ValuesymtabParser(const ValuesymtabParser &) = delete; | 930 ValuesymtabParser(const ValuesymtabParser &) = delete; |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
957 class FunctionParser : public BlockParserBaseClass { | 991 class FunctionParser : public BlockParserBaseClass { |
958 FunctionParser(const FunctionParser &) = delete; | 992 FunctionParser(const FunctionParser &) = delete; |
959 FunctionParser &operator=(const FunctionParser &) = delete; | 993 FunctionParser &operator=(const FunctionParser &) = delete; |
960 friend class FunctionValuesymtabParser; | 994 friend class FunctionValuesymtabParser; |
961 | 995 |
962 public: | 996 public: |
963 FunctionParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) | 997 FunctionParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) |
964 : BlockParserBaseClass(BlockID, EnclosingParser), | 998 : BlockParserBaseClass(BlockID, EnclosingParser), |
965 Func(new Ice::Cfg(getTranslator().getContext())), CurrentBbIndex(0), | 999 Func(new Ice::Cfg(getTranslator().getContext())), CurrentBbIndex(0), |
966 FcnId(Context->getNextFunctionBlockValueID()), | 1000 FcnId(Context->getNextFunctionBlockValueID()), |
967 LLVMFunc(Context->getFunctionByID(FcnId)), | 1001 FuncDecl(Context->getFunctionByID(FcnId)), |
968 CachedNumGlobalValueIDs(Context->getNumGlobalIDs()), | 1002 CachedNumGlobalValueIDs(Context->getNumGlobalIDs()), |
969 NextLocalInstIndex(Context->getNumGlobalIDs()), | 1003 NextLocalInstIndex(Context->getNumGlobalIDs()), |
970 InstIsTerminating(false) { | 1004 InstIsTerminating(false) { |
971 Func->setFunctionName(LLVMFunc->getName()); | 1005 Func->setFunctionName(FuncDecl->getName()); |
972 if (getFlags().TimeEachFunction) | 1006 if (getFlags().TimeEachFunction) |
973 getTranslator().getContext()->pushTimer( | 1007 getTranslator().getContext()->pushTimer( |
974 getTranslator().getContext()->getTimerID( | 1008 getTranslator().getContext()->getTimerID( |
975 Ice::GlobalContext::TSK_Funcs, Func->getFunctionName()), | 1009 Ice::GlobalContext::TSK_Funcs, Func->getFunctionName()), |
976 Ice::GlobalContext::TSK_Funcs); | 1010 Ice::GlobalContext::TSK_Funcs); |
977 Func->setReturnType(Context->convertToIceType(LLVMFunc->getReturnType())); | 1011 // TODO(kschimpf) Clean up API to add a function signature to |
978 Func->setInternal(LLVMFunc->hasInternalLinkage()); | 1012 // a CFG. |
| 1013 const Ice::FuncSigType &Signature = FuncDecl->getSignature(); |
| 1014 Func->setReturnType(Signature.getReturnType()); |
| 1015 Func->setInternal(FuncDecl->getLinkage() == GlobalValue::InternalLinkage); |
979 CurrentNode = InstallNextBasicBlock(); | 1016 CurrentNode = InstallNextBasicBlock(); |
980 Func->setEntryNode(CurrentNode); | 1017 Func->setEntryNode(CurrentNode); |
981 for (auto ArgI = LLVMFunc->arg_begin(), ArgE = LLVMFunc->arg_end(); | 1018 for (Ice::Type ArgType : Signature.getArgList()) { |
982 ArgI != ArgE; ++ArgI) { | 1019 Func->addArg(getNextInstVar(ArgType)); |
983 Func->addArg(getNextInstVar(Context->convertToIceType(ArgI->getType()))); | |
984 } | 1020 } |
985 } | 1021 } |
986 | 1022 |
987 ~FunctionParser() override {}; | 1023 ~FunctionParser() override {}; |
988 | 1024 |
989 // Set the next constant ID to the given constant C. | 1025 // Set the next constant ID to the given constant C. |
990 void setNextConstantID(Ice::Constant *C) { | 1026 void setNextConstantID(Ice::Constant *C) { |
991 setOperand(NextLocalInstIndex++, C); | 1027 setOperand(NextLocalInstIndex++, C); |
992 } | 1028 } |
993 | 1029 |
994 private: | 1030 private: |
995 // The corresponding ICE function defined by the function block. | 1031 // The corresponding ICE function defined by the function block. |
996 Ice::Cfg *Func; | 1032 Ice::Cfg *Func; |
997 // The index to the current basic block being built. | 1033 // The index to the current basic block being built. |
998 uint32_t CurrentBbIndex; | 1034 uint32_t CurrentBbIndex; |
999 // The basic block being built. | 1035 // The basic block being built. |
1000 Ice::CfgNode *CurrentNode; | 1036 Ice::CfgNode *CurrentNode; |
1001 // The ID for the function. | 1037 // The ID for the function. |
1002 unsigned FcnId; | 1038 unsigned FcnId; |
1003 // The corresponding LLVM function. | 1039 // The corresponding function declaration. |
1004 Function *LLVMFunc; | 1040 Ice::FunctionDeclaration *FuncDecl; |
1005 // Holds the dividing point between local and global absolute value indices. | 1041 // Holds the dividing point between local and global absolute value indices. |
1006 uint32_t CachedNumGlobalValueIDs; | 1042 uint32_t CachedNumGlobalValueIDs; |
1007 // Holds operands local to the function block, based on indices | 1043 // Holds operands local to the function block, based on indices |
1008 // defined in the bitcode file. | 1044 // defined in the bitcode file. |
1009 std::vector<Ice::Operand *> LocalOperands; | 1045 std::vector<Ice::Operand *> LocalOperands; |
1010 // Holds the index within LocalOperands corresponding to the next | 1046 // Holds the index within LocalOperands corresponding to the next |
1011 // instruction that generates a value. | 1047 // instruction that generates a value. |
1012 uint32_t NextLocalInstIndex; | 1048 uint32_t NextLocalInstIndex; |
1013 // True if the last processed instruction was a terminating | 1049 // True if the last processed instruction was a terminating |
1014 // instruction. | 1050 // instruction. |
(...skipping 977 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1992 CurrentNode->appendInst( | 2028 CurrentNode->appendInst( |
1993 Ice::InstStore::create(Func, Value, Address, Alignment)); | 2029 Ice::InstStore::create(Func, Value, Address, Alignment)); |
1994 break; | 2030 break; |
1995 } | 2031 } |
1996 case naclbitc::FUNC_CODE_INST_CALL: | 2032 case naclbitc::FUNC_CODE_INST_CALL: |
1997 case naclbitc::FUNC_CODE_INST_CALL_INDIRECT: { | 2033 case naclbitc::FUNC_CODE_INST_CALL_INDIRECT: { |
1998 // CALL: [cc, fnid, arg0, arg1...] | 2034 // CALL: [cc, fnid, arg0, arg1...] |
1999 // CALL_INDIRECT: [cc, fn, returnty, args...] | 2035 // CALL_INDIRECT: [cc, fn, returnty, args...] |
2000 // | 2036 // |
2001 // Note: The difference between CALL and CALL_INDIRECT is that | 2037 // Note: The difference between CALL and CALL_INDIRECT is that |
2002 // CALL has an explicit function address, while the CALL_INDIRECT | 2038 // CALL has a reference to an explicit function declaration, while |
2003 // is just an address. For CALL, we can infer the return type by | 2039 // the CALL_INDIRECT is just an address. For CALL, we can infer |
2004 // looking up the type signature associated with the function | 2040 // the return type by looking up the type signature associated |
2005 // address. For CALL_INDIRECT we can only infer the type signature | 2041 // with the function declaration. For CALL_INDIRECT we can only |
2006 // via argument types, and the corresponding return type stored in | 2042 // infer the type signature via argument types, and the |
2007 // CALL_INDIRECT record. | 2043 // corresponding return type stored in CALL_INDIRECT record. |
2008 Ice::SizeT ParamsStartIndex = 2; | 2044 Ice::SizeT ParamsStartIndex = 2; |
2009 if (Record.GetCode() == naclbitc::FUNC_CODE_INST_CALL) { | 2045 if (Record.GetCode() == naclbitc::FUNC_CODE_INST_CALL) { |
2010 if (!isValidRecordSizeAtLeast(2, "function block call")) | 2046 if (!isValidRecordSizeAtLeast(2, "function block call")) |
2011 return; | 2047 return; |
2012 } else { | 2048 } else { |
2013 if (!isValidRecordSizeAtLeast(3, "function block call indirect")) | 2049 if (!isValidRecordSizeAtLeast(3, "function block call indirect")) |
2014 return; | 2050 return; |
2015 ParamsStartIndex = 3; | 2051 ParamsStartIndex = 3; |
2016 } | 2052 } |
2017 | 2053 |
2018 // Extract call information. | 2054 // Extract call information. |
2019 uint64_t CCInfo = Values[0]; | 2055 uint64_t CCInfo = Values[0]; |
2020 CallingConv::ID CallingConv; | 2056 CallingConv::ID CallingConv; |
2021 if (!naclbitc::DecodeCallingConv(CCInfo >> 1, CallingConv)) { | 2057 if (!naclbitc::DecodeCallingConv(CCInfo >> 1, CallingConv)) { |
2022 std::string Buffer; | 2058 std::string Buffer; |
2023 raw_string_ostream StrBuf(Buffer); | 2059 raw_string_ostream StrBuf(Buffer); |
2024 StrBuf << "Function call calling convention value " << (CCInfo >> 1) | 2060 StrBuf << "Function call calling convention value " << (CCInfo >> 1) |
2025 << " not understood."; | 2061 << " not understood."; |
2026 Error(StrBuf.str()); | 2062 Error(StrBuf.str()); |
2027 return; | 2063 return; |
2028 } | 2064 } |
2029 bool IsTailCall = static_cast<bool>(CCInfo & 1); | 2065 bool IsTailCall = static_cast<bool>(CCInfo & 1); |
2030 | 2066 |
2031 // Extract out the called function and its return type. | 2067 // Extract out the called function and its return type. |
2032 uint32_t CalleeIndex = convertRelativeToAbsIndex(Values[1], BaseIndex); | 2068 uint32_t CalleeIndex = convertRelativeToAbsIndex(Values[1], BaseIndex); |
2033 Ice::Operand *Callee = getOperand(CalleeIndex); | 2069 Ice::Operand *Callee = getOperand(CalleeIndex); |
2034 Ice::Type ReturnType = Ice::IceType_void; | 2070 Ice::Type ReturnType = Ice::IceType_void; |
2035 const Ice::Intrinsics::FullIntrinsicInfo *IntrinsicInfo = nullptr; | 2071 const Ice::Intrinsics::FullIntrinsicInfo *IntrinsicInfo = nullptr; |
2036 if (Record.GetCode() == naclbitc::FUNC_CODE_INST_CALL) { | 2072 if (Record.GetCode() == naclbitc::FUNC_CODE_INST_CALL) { |
2037 Function *Fcn = Context->getFunctionByID(CalleeIndex); | 2073 Ice::FunctionDeclaration *Fcn = Context->getFunctionByID(CalleeIndex); |
2038 if (Fcn == nullptr) { | 2074 const Ice::FuncSigType &Signature = Fcn->getSignature(); |
2039 std::string Buffer; | 2075 ReturnType = Signature.getReturnType(); |
2040 raw_string_ostream StrBuf(Buffer); | |
2041 StrBuf << "Function call to non-function: " << *Callee; | |
2042 Error(StrBuf.str()); | |
2043 return; | |
2044 } | |
2045 | |
2046 FunctionType *FcnTy = Fcn->getFunctionType(); | |
2047 ReturnType = Context->convertToIceType(FcnTy->getReturnType()); | |
2048 | 2076 |
2049 // Check if this direct call is to an Intrinsic (starts with "llvm.") | 2077 // Check if this direct call is to an Intrinsic (starts with "llvm.") |
2050 static Ice::IceString LLVMPrefix("llvm."); | 2078 static Ice::IceString LLVMPrefix("llvm."); |
2051 Ice::IceString Name = Fcn->getName(); | 2079 Ice::IceString Name = Fcn->getName(); |
2052 if (isStringPrefix(Name, LLVMPrefix)) { | 2080 if (isStringPrefix(Name, LLVMPrefix)) { |
2053 Ice::IceString Suffix = Name.substr(LLVMPrefix.size()); | 2081 Ice::IceString Suffix = Name.substr(LLVMPrefix.size()); |
2054 IntrinsicInfo = | 2082 IntrinsicInfo = |
2055 getTranslator().getContext()->getIntrinsicsInfo().find(Suffix); | 2083 getTranslator().getContext()->getIntrinsicsInfo().find(Suffix); |
2056 if (!IntrinsicInfo) { | 2084 if (!IntrinsicInfo) { |
2057 std::string Buffer; | 2085 std::string Buffer; |
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2332 break; | 2360 break; |
2333 } | 2361 } |
2334 return BlockParserBaseClass::ParseBlock(BlockID); | 2362 return BlockParserBaseClass::ParseBlock(BlockID); |
2335 } | 2363 } |
2336 | 2364 |
2337 /// Parses the module block in the bitcode file. | 2365 /// Parses the module block in the bitcode file. |
2338 class ModuleParser : public BlockParserBaseClass { | 2366 class ModuleParser : public BlockParserBaseClass { |
2339 public: | 2367 public: |
2340 ModuleParser(unsigned BlockID, TopLevelParser *Context) | 2368 ModuleParser(unsigned BlockID, TopLevelParser *Context) |
2341 : BlockParserBaseClass(BlockID, Context), | 2369 : BlockParserBaseClass(BlockID, Context), |
2342 GlobalAddressNamesAndInitializersInstalled(false) {} | 2370 GlobalDeclarationNamesAndInitializersInstalled(false) {} |
2343 | 2371 |
2344 ~ModuleParser() override {} | 2372 ~ModuleParser() override {} |
2345 | 2373 |
2346 private: | 2374 private: |
2347 // True if we have already instaledl names for unnamed global addresses, | 2375 // True if we have already installed names for unnamed global declarations, |
2348 // and generated global constant initializers. | 2376 // and have generated global constant initializers. |
2349 bool GlobalAddressNamesAndInitializersInstalled; | 2377 bool GlobalDeclarationNamesAndInitializersInstalled; |
2350 | 2378 |
2351 // Generates names for unnamed global addresses, and lowers global | 2379 // Generates names for unnamed global addresses (i.e. functions and |
2352 // constant initializers to the target. May be called multiple | 2380 // global variables). Then lowers global variable declaration |
2353 // times. Only the first call will do the installation. | 2381 // initializers to the target. May be called multiple times. Only |
2354 void InstallGlobalAddressNamesAndInitializers() { | 2382 // the first call will do the installation. |
2355 if (!GlobalAddressNamesAndInitializersInstalled) { | 2383 void InstallGlobalNamesAndGlobalVarInitializers() { |
| 2384 if (!GlobalDeclarationNamesAndInitializersInstalled) { |
2356 Ice::Translator &Trans = getTranslator(); | 2385 Ice::Translator &Trans = getTranslator(); |
2357 const Ice::IceString &GlobalPrefix = getFlags().DefaultGlobalPrefix; | 2386 const Ice::IceString &GlobalPrefix = getFlags().DefaultGlobalPrefix; |
2358 if (!GlobalPrefix.empty()) { | 2387 if (!GlobalPrefix.empty()) { |
2359 uint32_t NameIndex = 0; | 2388 uint32_t NameIndex = 0; |
2360 for (Ice::GlobalAddress *Address : Context->getGlobalIDAddresses()) { | 2389 for (Ice::VariableDeclaration *Var : Context->getGlobalVariables()) { |
2361 if (!Address->hasName()) { | 2390 installDeclarationName(Trans, Var, GlobalPrefix, "global", NameIndex); |
2362 Address->setName(Trans.createUnnamedName(GlobalPrefix, NameIndex)); | |
2363 ++NameIndex; | |
2364 } else { | |
2365 Trans.checkIfUnnamedNameSafe(Address->getName(), "global", | |
2366 GlobalPrefix, | |
2367 Trans.getContext()->getStrDump()); | |
2368 } | |
2369 } | 2391 } |
2370 } | 2392 } |
2371 Trans.nameUnnamedFunctions(Context->getModule()); | 2393 const Ice::IceString &FunctionPrefix = getFlags().DefaultFunctionPrefix; |
2372 getTranslator().lowerGlobals(Context->getGlobalIDAddresses()); | 2394 if (!FunctionPrefix.empty()) { |
2373 GlobalAddressNamesAndInitializersInstalled = true; | 2395 uint32_t NameIndex = 0; |
| 2396 for (Ice::FunctionDeclaration *Func : |
| 2397 Context->getFunctionDeclarationList()) { |
| 2398 installDeclarationName(Trans, Func, FunctionPrefix, "function", |
| 2399 NameIndex); |
| 2400 } |
| 2401 } |
| 2402 getTranslator().lowerGlobals(Context->getGlobalVariables()); |
| 2403 GlobalDeclarationNamesAndInitializersInstalled = true; |
| 2404 } |
| 2405 } |
| 2406 |
| 2407 void installDeclarationName(Ice::Translator &Trans, |
| 2408 Ice::GlobalDeclaration *Decl, |
| 2409 const Ice::IceString &Prefix, const char *Context, |
| 2410 uint32_t &NameIndex) { |
| 2411 if (!Decl->hasName()) { |
| 2412 Decl->setName(Trans.createUnnamedName(Prefix, NameIndex)); |
| 2413 ++NameIndex; |
| 2414 } else { |
| 2415 Trans.checkIfUnnamedNameSafe(Decl->getName(), Context, Prefix, |
| 2416 Trans.getContext()->getStrDump()); |
2374 } | 2417 } |
2375 } | 2418 } |
2376 | 2419 |
2377 bool ParseBlock(unsigned BlockID) override; | 2420 bool ParseBlock(unsigned BlockID) override; |
2378 | 2421 |
2379 void ExitBlock() override { | 2422 void ExitBlock() override { |
2380 InstallGlobalAddressNamesAndInitializers(); | 2423 InstallGlobalNamesAndGlobalVarInitializers(); |
2381 getTranslator().emitConstants(); | 2424 getTranslator().emitConstants(); |
2382 } | 2425 } |
2383 | 2426 |
2384 void ProcessRecord() override; | 2427 void ProcessRecord() override; |
2385 }; | 2428 }; |
2386 | 2429 |
2387 class ModuleValuesymtabParser : public ValuesymtabParser { | 2430 class ModuleValuesymtabParser : public ValuesymtabParser { |
2388 ModuleValuesymtabParser(const ModuleValuesymtabParser &) = delete; | 2431 ModuleValuesymtabParser(const ModuleValuesymtabParser &) = delete; |
2389 void operator=(const ModuleValuesymtabParser &) = delete; | 2432 void operator=(const ModuleValuesymtabParser &) = delete; |
2390 | 2433 |
2391 public: | 2434 public: |
2392 ModuleValuesymtabParser(unsigned BlockID, ModuleParser *MP) | 2435 ModuleValuesymtabParser(unsigned BlockID, ModuleParser *MP) |
2393 : ValuesymtabParser(BlockID, MP) {} | 2436 : ValuesymtabParser(BlockID, MP) {} |
2394 | 2437 |
2395 ~ModuleValuesymtabParser() override {} | 2438 ~ModuleValuesymtabParser() override {} |
2396 | 2439 |
2397 private: | 2440 private: |
2398 void setValueName(uint64_t Index, StringType &Name) override; | 2441 void setValueName(uint64_t Index, StringType &Name) override; |
2399 void setBbName(uint64_t Index, StringType &Name) override; | 2442 void setBbName(uint64_t Index, StringType &Name) override; |
2400 }; | 2443 }; |
2401 | 2444 |
2402 void ModuleValuesymtabParser::setValueName(uint64_t Index, StringType &Name) { | 2445 void ModuleValuesymtabParser::setValueName(uint64_t Index, StringType &Name) { |
2403 if (Index < Context->getNumFunctionIDs()) { | 2446 Context->getGlobalDeclarationByID(Index) |
2404 Function *Fcn = Context->getFunctionByID(Index); | 2447 ->setName(StringRef(Name.data(), Name.size())); |
2405 if (Fcn != nullptr) { | |
2406 Fcn->setName(StringRef(Name.data(), Name.size())); | |
2407 return; | |
2408 } | |
2409 } else { | |
2410 unsigned NumFunctions = Context->getNumFunctionIDs(); | |
2411 if (Index >= NumFunctions) { | |
2412 Context->getGlobalAddress(Index - NumFunctions) | |
2413 ->setName(StringRef(Name.data(), Name.size())); | |
2414 } | |
2415 return; | |
2416 } | |
2417 | |
2418 std::string Buffer; | |
2419 raw_string_ostream StrBuf(Buffer); | |
2420 StrBuf << "Invalid global address ID in valuesymtab: " << Index; | |
2421 Error(StrBuf.str()); | |
2422 return; | |
2423 } | 2448 } |
2424 | 2449 |
2425 void ModuleValuesymtabParser::setBbName(uint64_t Index, StringType &Name) { | 2450 void ModuleValuesymtabParser::setBbName(uint64_t Index, StringType &Name) { |
2426 std::string Buffer; | 2451 std::string Buffer; |
2427 raw_string_ostream StrBuf(Buffer); | 2452 raw_string_ostream StrBuf(Buffer); |
2428 StrBuf << "Can't define basic block name at global level: '" << Name | 2453 StrBuf << "Can't define basic block name at global level: '" << Name |
2429 << "' -> " << Index; | 2454 << "' -> " << Index; |
2430 Error(StrBuf.str()); | 2455 Error(StrBuf.str()); |
2431 } | 2456 } |
2432 | 2457 |
2433 bool ModuleParser::ParseBlock(unsigned BlockID) { | 2458 bool ModuleParser::ParseBlock(unsigned BlockID) { |
2434 switch (BlockID) { | 2459 switch (BlockID) { |
2435 case naclbitc::BLOCKINFO_BLOCK_ID: | 2460 case naclbitc::BLOCKINFO_BLOCK_ID: |
2436 return NaClBitcodeParser::ParseBlock(BlockID); | 2461 return NaClBitcodeParser::ParseBlock(BlockID); |
2437 case naclbitc::TYPE_BLOCK_ID_NEW: { | 2462 case naclbitc::TYPE_BLOCK_ID_NEW: { |
2438 TypesParser Parser(BlockID, this); | 2463 TypesParser Parser(BlockID, this); |
2439 return Parser.ParseThisBlock(); | 2464 return Parser.ParseThisBlock(); |
2440 } | 2465 } |
2441 case naclbitc::GLOBALVAR_BLOCK_ID: { | 2466 case naclbitc::GLOBALVAR_BLOCK_ID: { |
2442 GlobalsParser Parser(BlockID, this); | 2467 GlobalsParser Parser(BlockID, this); |
2443 return Parser.ParseThisBlock(); | 2468 return Parser.ParseThisBlock(); |
2444 } | 2469 } |
2445 case naclbitc::VALUE_SYMTAB_BLOCK_ID: { | 2470 case naclbitc::VALUE_SYMTAB_BLOCK_ID: { |
2446 ModuleValuesymtabParser Parser(BlockID, this); | 2471 ModuleValuesymtabParser Parser(BlockID, this); |
2447 return Parser.ParseThisBlock(); | 2472 return Parser.ParseThisBlock(); |
2448 } | 2473 } |
2449 case naclbitc::FUNCTION_BLOCK_ID: { | 2474 case naclbitc::FUNCTION_BLOCK_ID: { |
2450 InstallGlobalAddressNamesAndInitializers(); | 2475 InstallGlobalNamesAndGlobalVarInitializers(); |
2451 FunctionParser Parser(BlockID, this); | 2476 FunctionParser Parser(BlockID, this); |
2452 return Parser.ParseThisBlock(); | 2477 return Parser.ParseThisBlock(); |
2453 } | 2478 } |
2454 default: | 2479 default: |
2455 return BlockParserBaseClass::ParseBlock(BlockID); | 2480 return BlockParserBaseClass::ParseBlock(BlockID); |
2456 } | 2481 } |
2457 } | 2482 } |
2458 | 2483 |
2459 void ModuleParser::ProcessRecord() { | 2484 void ModuleParser::ProcessRecord() { |
2460 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); | 2485 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); |
2461 switch (Record.GetCode()) { | 2486 switch (Record.GetCode()) { |
2462 case naclbitc::MODULE_CODE_VERSION: { | 2487 case naclbitc::MODULE_CODE_VERSION: { |
2463 // VERSION: [version#] | 2488 // VERSION: [version#] |
2464 if (!isValidRecordSize(1, "Module version")) | 2489 if (!isValidRecordSize(1, "Module version")) |
2465 return; | 2490 return; |
2466 unsigned Version = Values[0]; | 2491 unsigned Version = Values[0]; |
2467 if (Version != 1) { | 2492 if (Version != 1) { |
2468 std::string Buffer; | 2493 std::string Buffer; |
2469 raw_string_ostream StrBuf(Buffer); | 2494 raw_string_ostream StrBuf(Buffer); |
2470 StrBuf << "Unknown bitstream version: " << Version; | 2495 StrBuf << "Unknown bitstream version: " << Version; |
2471 Error(StrBuf.str()); | 2496 Error(StrBuf.str()); |
2472 } | 2497 } |
2473 return; | 2498 return; |
2474 } | 2499 } |
2475 case naclbitc::MODULE_CODE_FUNCTION: { | 2500 case naclbitc::MODULE_CODE_FUNCTION: { |
2476 // FUNCTION: [type, callingconv, isproto, linkage] | 2501 // FUNCTION: [type, callingconv, isproto, linkage] |
2477 if (!isValidRecordSize(4, "Function heading")) | 2502 if (!isValidRecordSize(4, "Function heading")) |
2478 return; | 2503 return; |
2479 const Ice::FuncSigType &Ty = Context->getFuncSigTypeByID(Values[0]); | 2504 const Ice::FuncSigType &Signature = Context->getFuncSigTypeByID(Values[0]); |
2480 CallingConv::ID CallingConv; | 2505 CallingConv::ID CallingConv; |
2481 if (!naclbitc::DecodeCallingConv(Values[1], CallingConv)) { | 2506 if (!naclbitc::DecodeCallingConv(Values[1], CallingConv)) { |
2482 std::string Buffer; | 2507 std::string Buffer; |
2483 raw_string_ostream StrBuf(Buffer); | 2508 raw_string_ostream StrBuf(Buffer); |
2484 StrBuf << "Function heading has unknown calling convention: " | 2509 StrBuf << "Function heading has unknown calling convention: " |
2485 << Values[1]; | 2510 << Values[1]; |
2486 Error(StrBuf.str()); | 2511 Error(StrBuf.str()); |
2487 return; | 2512 return; |
2488 } | 2513 } |
2489 GlobalValue::LinkageTypes Linkage; | 2514 GlobalValue::LinkageTypes Linkage; |
2490 if (!naclbitc::DecodeLinkage(Values[3], Linkage)) { | 2515 if (!naclbitc::DecodeLinkage(Values[3], Linkage)) { |
2491 std::string Buffer; | 2516 std::string Buffer; |
2492 raw_string_ostream StrBuf(Buffer); | 2517 raw_string_ostream StrBuf(Buffer); |
2493 StrBuf << "Function heading has unknown linkage. Found " << Values[3]; | 2518 StrBuf << "Function heading has unknown linkage. Found " << Values[3]; |
2494 Error(StrBuf.str()); | 2519 Error(StrBuf.str()); |
2495 return; | 2520 return; |
2496 } | 2521 } |
2497 SmallVector<Type *, 8> ArgTys; | 2522 Ice::FunctionDeclaration *Func = Ice::FunctionDeclaration::create( |
2498 for (Ice::Type ArgType : Ty.getArgList()) { | 2523 getTranslator().getContext(), Signature, CallingConv, Linkage, |
2499 ArgTys.push_back(Context->convertToLLVMType(ArgType)); | 2524 Values[2] == 0); |
2500 } | |
2501 Function *Func = Function::Create( | |
2502 FunctionType::get(Context->convertToLLVMType(Ty.getReturnType()), | |
2503 ArgTys, false), | |
2504 Linkage, "", Context->getModule()); | |
2505 Func->setCallingConv(CallingConv); | |
2506 if (Values[2] == 0) | 2525 if (Values[2] == 0) |
2507 Context->setNextValueIDAsImplementedFunction(); | 2526 Context->setNextValueIDAsImplementedFunction(); |
2508 Context->setNextFunctionID(Func); | 2527 Context->setNextFunctionID(Func); |
2509 // TODO(kschimpf) verify if Func matches PNaCl ABI. | |
2510 return; | 2528 return; |
2511 } | 2529 } |
2512 default: | 2530 default: |
2513 BlockParserBaseClass::ProcessRecord(); | 2531 BlockParserBaseClass::ProcessRecord(); |
2514 return; | 2532 return; |
2515 } | 2533 } |
2516 } | 2534 } |
2517 | 2535 |
2518 bool TopLevelParser::ParseBlock(unsigned BlockID) { | 2536 bool TopLevelParser::ParseBlock(unsigned BlockID) { |
2519 if (BlockID == naclbitc::MODULE_BLOCK_ID) { | 2537 if (BlockID == naclbitc::MODULE_BLOCK_ID) { |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2573 | 2591 |
2574 if (TopLevelBlocks != 1) { | 2592 if (TopLevelBlocks != 1) { |
2575 errs() << IRFilename | 2593 errs() << IRFilename |
2576 << ": Contains more than one module. Found: " << TopLevelBlocks | 2594 << ": Contains more than one module. Found: " << TopLevelBlocks |
2577 << "\n"; | 2595 << "\n"; |
2578 ErrorStatus = true; | 2596 ErrorStatus = true; |
2579 } | 2597 } |
2580 } | 2598 } |
2581 | 2599 |
2582 } // end of namespace Ice | 2600 } // end of namespace Ice |
OLD | NEW |