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 /// \file | 10 /// \file |
(...skipping 23 matching lines...) Expand all Loading... |
34 #include "llvm/Bitcode/NaCl/NaClBitcodeParser.h" | 34 #include "llvm/Bitcode/NaCl/NaClBitcodeParser.h" |
35 #include "llvm/Bitcode/NaCl/NaClReaderWriter.h" | 35 #include "llvm/Bitcode/NaCl/NaClReaderWriter.h" |
36 #include "llvm/Support/Format.h" | 36 #include "llvm/Support/Format.h" |
37 #include "llvm/Support/MemoryBuffer.h" | 37 #include "llvm/Support/MemoryBuffer.h" |
38 #include "llvm/Support/raw_ostream.h" | 38 #include "llvm/Support/raw_ostream.h" |
39 #pragma clang diagnostic pop | 39 #pragma clang diagnostic pop |
40 | 40 |
41 namespace { | 41 namespace { |
42 using namespace llvm; | 42 using namespace llvm; |
43 | 43 |
44 // Models elements in the list of types defined in the types block. | 44 // Models elements in the list of types defined in the types block. These |
45 // These elements can be undefined, a (simple) type, or a function type | 45 // elements can be undefined, a (simple) type, or a function type signature. |
46 // signature. Note that an extended type is undefined on construction. | 46 // Note that an extended type is undefined on construction. Use methods |
47 // Use methods setAsSimpleType and setAsFuncSigType to define | 47 // setAsSimpleType and setAsFuncSigType to define the extended type. |
48 // the extended type. | |
49 class ExtendedType { | 48 class ExtendedType { |
50 ExtendedType &operator=(const ExtendedType &Ty) = delete; | 49 ExtendedType &operator=(const ExtendedType &Ty) = delete; |
51 | 50 |
52 public: | 51 public: |
53 /// Discriminator for LLVM-style RTTI. | 52 /// Discriminator for LLVM-style RTTI. |
54 enum TypeKind { Undefined, Simple, FuncSig }; | 53 enum TypeKind { Undefined, Simple, FuncSig }; |
55 | 54 |
56 ExtendedType() = default; | 55 ExtendedType() = default; |
57 ExtendedType(const ExtendedType &Ty) = default; | 56 ExtendedType(const ExtendedType &Ty) = default; |
58 | 57 |
59 virtual ~ExtendedType() = default; | 58 virtual ~ExtendedType() = default; |
60 | 59 |
61 ExtendedType::TypeKind getKind() const { return Kind; } | 60 ExtendedType::TypeKind getKind() const { return Kind; } |
62 void dump(Ice::Ostream &Stream) const; | 61 void dump(Ice::Ostream &Stream) const; |
63 | 62 |
64 /// Changes the extended type to a simple type with the given | 63 /// Changes the extended type to a simple type with the given / value. |
65 /// value. | |
66 void setAsSimpleType(Ice::Type Ty) { | 64 void setAsSimpleType(Ice::Type Ty) { |
67 assert(Kind == Undefined); | 65 assert(Kind == Undefined); |
68 Kind = Simple; | 66 Kind = Simple; |
69 Signature.setReturnType(Ty); | 67 Signature.setReturnType(Ty); |
70 } | 68 } |
71 | 69 |
72 /// Changes the extended type to an (empty) function signature type. | 70 /// Changes the extended type to an (empty) function signature type. |
73 void setAsFunctionType() { | 71 void setAsFunctionType() { |
74 assert(Kind == Undefined); | 72 assert(Kind == Undefined); |
75 Kind = FuncSig; | 73 Kind = FuncSig; |
76 } | 74 } |
77 | 75 |
78 protected: | 76 protected: |
79 // Note: For simple types, the return type of the signature will | 77 // Note: For simple types, the return type of the signature will be used to |
80 // be used to hold the simple type. | 78 // hold the simple type. |
81 Ice::FuncSigType Signature; | 79 Ice::FuncSigType Signature; |
82 | 80 |
83 private: | 81 private: |
84 ExtendedType::TypeKind Kind = Undefined; | 82 ExtendedType::TypeKind Kind = Undefined; |
85 }; | 83 }; |
86 | 84 |
87 Ice::Ostream &operator<<(Ice::Ostream &Stream, const ExtendedType &Ty) { | 85 Ice::Ostream &operator<<(Ice::Ostream &Stream, const ExtendedType &Ty) { |
88 if (!Ice::BuildDefs::dump()) | 86 if (!Ice::BuildDefs::dump()) |
89 return Stream; | 87 return Stream; |
90 Ty.dump(Stream); | 88 Ty.dump(Stream); |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
173 VariableDeclarations(new Ice::VariableDeclarationList()) {} | 171 VariableDeclarations(new Ice::VariableDeclarationList()) {} |
174 | 172 |
175 ~TopLevelParser() override = default; | 173 ~TopLevelParser() override = default; |
176 | 174 |
177 Ice::Translator &getTranslator() const { return Translator; } | 175 Ice::Translator &getTranslator() const { return Translator; } |
178 | 176 |
179 void setBlockParser(BlockParserBaseClass *NewBlockParser) { | 177 void setBlockParser(BlockParserBaseClass *NewBlockParser) { |
180 BlockParser = NewBlockParser; | 178 BlockParser = NewBlockParser; |
181 } | 179 } |
182 | 180 |
183 /// Generates error with given Message, occurring at BitPosition | 181 /// Generates error with given Message, occurring at BitPosition within the |
184 /// within the bitcode file. Always returns true. | 182 /// bitcode file. Always returns true. |
185 bool ErrorAt(naclbitc::ErrorLevel Level, uint64_t BitPosition, | 183 bool ErrorAt(naclbitc::ErrorLevel Level, uint64_t BitPosition, |
186 const std::string &Message) final; | 184 const std::string &Message) final; |
187 | 185 |
188 /// Generates error message with respect to the current block parser. | 186 /// Generates error message with respect to the current block parser. |
189 bool blockError(const std::string &Message); | 187 bool blockError(const std::string &Message); |
190 | 188 |
191 /// Returns the number of errors found while parsing the bitcode | 189 /// Returns the number of errors found while parsing the bitcode file. |
192 /// file. | |
193 unsigned getNumErrors() const { return NumErrors; } | 190 unsigned getNumErrors() const { return NumErrors; } |
194 | 191 |
195 /// Changes the size of the type list to the given size. | 192 /// Changes the size of the type list to the given size. |
196 void resizeTypeIDValues(size_t NewSize) { TypeIDValues.resize(NewSize); } | 193 void resizeTypeIDValues(size_t NewSize) { TypeIDValues.resize(NewSize); } |
197 | 194 |
198 size_t getNumTypeIDValues() const { return TypeIDValues.size(); } | 195 size_t getNumTypeIDValues() const { return TypeIDValues.size(); } |
199 | 196 |
200 /// Returns true if generation of Subzero IR is disabled. | 197 /// Returns true if generation of Subzero IR is disabled. |
201 bool isIRGenerationDisabled() const { | 198 bool isIRGenerationDisabled() const { |
202 return Translator.getFlags().getDisableIRGeneration(); | 199 return Translator.getFlags().getDisableIRGeneration(); |
203 } | 200 } |
204 | 201 |
205 /// Returns the undefined type associated with type ID. | 202 /// Returns the undefined type associated with type ID. Note: Returns extended |
206 /// Note: Returns extended type ready to be defined. | 203 /// type ready to be defined. |
207 ExtendedType *getTypeByIDForDefining(NaClBcIndexSize_t ID) { | 204 ExtendedType *getTypeByIDForDefining(NaClBcIndexSize_t ID) { |
208 // Get corresponding element, verifying the value is still undefined | 205 // Get corresponding element, verifying the value is still undefined (and |
209 // (and hence allowed to be defined). | 206 // hence allowed to be defined). |
210 ExtendedType *Ty = getTypeByIDAsKind(ID, ExtendedType::Undefined); | 207 ExtendedType *Ty = getTypeByIDAsKind(ID, ExtendedType::Undefined); |
211 if (Ty) | 208 if (Ty) |
212 return Ty; | 209 return Ty; |
213 if (ID >= TypeIDValues.size()) { | 210 if (ID >= TypeIDValues.size()) { |
214 if (ID >= NaClBcIndexSize_t_Max) { | 211 if (ID >= NaClBcIndexSize_t_Max) { |
215 std::string Buffer; | 212 std::string Buffer; |
216 raw_string_ostream StrBuf(Buffer); | 213 raw_string_ostream StrBuf(Buffer); |
217 StrBuf << "Can't define more than " << NaClBcIndexSize_t_Max | 214 StrBuf << "Can't define more than " << NaClBcIndexSize_t_Max |
218 << " types\n"; | 215 << " types\n"; |
219 blockError(StrBuf.str()); | 216 blockError(StrBuf.str()); |
(...skipping 21 matching lines...) Expand all Loading... |
241 // Return error recovery value. | 238 // Return error recovery value. |
242 return UndefinedFuncSigType; | 239 return UndefinedFuncSigType; |
243 return cast<FuncSigExtendedType>(Ty)->getSignature(); | 240 return cast<FuncSigExtendedType>(Ty)->getSignature(); |
244 } | 241 } |
245 | 242 |
246 /// Sets the next function ID to the given LLVM function. | 243 /// Sets the next function ID to the given LLVM function. |
247 void setNextFunctionID(Ice::FunctionDeclaration *Fcn) { | 244 void setNextFunctionID(Ice::FunctionDeclaration *Fcn) { |
248 FunctionDeclarations.push_back(Fcn); | 245 FunctionDeclarations.push_back(Fcn); |
249 } | 246 } |
250 | 247 |
251 /// Returns the value id that should be associated with the the | 248 /// Returns the value id that should be associated with the the current |
252 /// current function block. Increments internal counters during call | 249 /// function block. Increments internal counters during call so that it will |
253 /// so that it will be in correct position for next function block. | 250 /// be in correct position for next function block. |
254 NaClBcIndexSize_t getNextFunctionBlockValueID() { | 251 NaClBcIndexSize_t getNextFunctionBlockValueID() { |
255 size_t NumDeclaredFunctions = FunctionDeclarations.size(); | 252 size_t NumDeclaredFunctions = FunctionDeclarations.size(); |
256 while (NextDefiningFunctionID < NumDeclaredFunctions && | 253 while (NextDefiningFunctionID < NumDeclaredFunctions && |
257 FunctionDeclarations[NextDefiningFunctionID]->isProto()) | 254 FunctionDeclarations[NextDefiningFunctionID]->isProto()) |
258 ++NextDefiningFunctionID; | 255 ++NextDefiningFunctionID; |
259 if (NextDefiningFunctionID >= NumDeclaredFunctions) | 256 if (NextDefiningFunctionID >= NumDeclaredFunctions) |
260 Fatal("More function blocks than defined function addresses"); | 257 Fatal("More function blocks than defined function addresses"); |
261 return NextDefiningFunctionID++; | 258 return NextDefiningFunctionID++; |
262 } | 259 } |
263 | 260 |
264 /// Returns the function associated with ID. | 261 /// Returns the function associated with ID. |
265 Ice::FunctionDeclaration *getFunctionByID(NaClBcIndexSize_t ID) { | 262 Ice::FunctionDeclaration *getFunctionByID(NaClBcIndexSize_t ID) { |
266 if (ID < FunctionDeclarations.size()) | 263 if (ID < FunctionDeclarations.size()) |
267 return FunctionDeclarations[ID]; | 264 return FunctionDeclarations[ID]; |
268 return reportGetFunctionByIDError(ID); | 265 return reportGetFunctionByIDError(ID); |
269 } | 266 } |
270 | 267 |
271 /// Returns the constant associated with the given global value ID. | 268 /// Returns the constant associated with the given global value ID. |
272 Ice::Constant *getGlobalConstantByID(NaClBcIndexSize_t ID) { | 269 Ice::Constant *getGlobalConstantByID(NaClBcIndexSize_t ID) { |
273 assert(ID < ValueIDConstants.size()); | 270 assert(ID < ValueIDConstants.size()); |
274 return ValueIDConstants[ID]; | 271 return ValueIDConstants[ID]; |
275 } | 272 } |
276 | 273 |
277 /// Install names for all global values without names. Called after | 274 /// Install names for all global values without names. Called after the global |
278 /// the global value symbol table is processed, but before any | 275 /// value symbol table is processed, but before any function blocks are |
279 /// function blocks are processed. | 276 /// processed. |
280 void installGlobalNames() { | 277 void installGlobalNames() { |
281 assert(VariableDeclarations); | 278 assert(VariableDeclarations); |
282 installGlobalVarNames(); | 279 installGlobalVarNames(); |
283 installFunctionNames(); | 280 installFunctionNames(); |
284 } | 281 } |
285 | 282 |
286 void createValueIDs() { | 283 void createValueIDs() { |
287 assert(VariableDeclarations); | 284 assert(VariableDeclarations); |
288 ValueIDConstants.reserve(VariableDeclarations->size() + | 285 ValueIDConstants.reserve(VariableDeclarations->size() + |
289 FunctionDeclarations.size()); | 286 FunctionDeclarations.size()); |
290 createValueIDsForFunctions(); | 287 createValueIDsForFunctions(); |
291 createValueIDsForGlobalVars(); | 288 createValueIDsForGlobalVars(); |
292 } | 289 } |
293 | 290 |
294 /// Returns the number of function declarations in the bitcode file. | 291 /// Returns the number of function declarations in the bitcode file. |
295 size_t getNumFunctionIDs() const { return FunctionDeclarations.size(); } | 292 size_t getNumFunctionIDs() const { return FunctionDeclarations.size(); } |
296 | 293 |
297 /// Returns the number of global declarations (i.e. IDs) defined in | 294 /// Returns the number of global declarations (i.e. IDs) defined in the |
298 /// the bitcode file. | 295 /// bitcode file. |
299 size_t getNumGlobalIDs() const { | 296 size_t getNumGlobalIDs() const { |
300 if (VariableDeclarations) { | 297 if (VariableDeclarations) { |
301 return FunctionDeclarations.size() + VariableDeclarations->size(); | 298 return FunctionDeclarations.size() + VariableDeclarations->size(); |
302 } else { | 299 } else { |
303 return ValueIDConstants.size(); | 300 return ValueIDConstants.size(); |
304 } | 301 } |
305 } | 302 } |
306 | 303 |
307 /// Adds the given global declaration to the end of the list of global | 304 /// Adds the given global declaration to the end of the list of global |
308 /// declarations. | 305 /// declarations. |
309 void addGlobalDeclaration(Ice::VariableDeclaration *Decl) { | 306 void addGlobalDeclaration(Ice::VariableDeclaration *Decl) { |
310 assert(VariableDeclarations); | 307 assert(VariableDeclarations); |
311 VariableDeclarations->push_back(Decl); | 308 VariableDeclarations->push_back(Decl); |
312 } | 309 } |
313 | 310 |
314 /// Returns the global variable declaration with the given index. | 311 /// Returns the global variable declaration with the given index. |
315 Ice::VariableDeclaration *getGlobalVariableByID(NaClBcIndexSize_t Index) { | 312 Ice::VariableDeclaration *getGlobalVariableByID(NaClBcIndexSize_t Index) { |
316 assert(VariableDeclarations); | 313 assert(VariableDeclarations); |
317 if (Index < VariableDeclarations->size()) | 314 if (Index < VariableDeclarations->size()) |
318 return VariableDeclarations->at(Index); | 315 return VariableDeclarations->at(Index); |
319 return reportGetGlobalVariableByIDError(Index); | 316 return reportGetGlobalVariableByIDError(Index); |
320 } | 317 } |
321 | 318 |
322 /// Returns the global declaration (variable or function) with the | 319 /// Returns the global declaration (variable or function) with the given |
323 /// given Index. | 320 /// Index. |
324 Ice::GlobalDeclaration *getGlobalDeclarationByID(NaClBcIndexSize_t Index) { | 321 Ice::GlobalDeclaration *getGlobalDeclarationByID(NaClBcIndexSize_t Index) { |
325 size_t NumFunctionIds = FunctionDeclarations.size(); | 322 size_t NumFunctionIds = FunctionDeclarations.size(); |
326 if (Index < NumFunctionIds) | 323 if (Index < NumFunctionIds) |
327 return getFunctionByID(Index); | 324 return getFunctionByID(Index); |
328 else | 325 else |
329 return getGlobalVariableByID(Index - NumFunctionIds); | 326 return getGlobalVariableByID(Index - NumFunctionIds); |
330 } | 327 } |
331 | 328 |
332 /// Returns the list of parsed global variable | 329 /// Returns the list of parsed global variable declarations. Releases |
333 /// declarations. Releases ownership of the current list of global | 330 /// ownership of the current list of global variables. Note: only returns |
334 /// variables. Note: only returns non-null pointer on first | 331 /// non-null pointer on first call. All successive calls return a null |
335 /// call. All successive calls return a null pointer. | 332 /// pointer. |
336 std::unique_ptr<Ice::VariableDeclarationList> getGlobalVariables() { | 333 std::unique_ptr<Ice::VariableDeclarationList> getGlobalVariables() { |
337 // Before returning, check that ValidIDConstants has already been | 334 // Before returning, check that ValidIDConstants has already been built. |
338 // built. | |
339 assert(!VariableDeclarations || | 335 assert(!VariableDeclarations || |
340 VariableDeclarations->size() <= ValueIDConstants.size()); | 336 VariableDeclarations->size() <= ValueIDConstants.size()); |
341 return std::move(VariableDeclarations); | 337 return std::move(VariableDeclarations); |
342 } | 338 } |
343 | 339 |
344 private: | 340 private: |
345 // The translator associated with the parser. | 341 // The translator associated with the parser. |
346 Ice::Translator &Translator; | 342 Ice::Translator &Translator; |
347 // The exit status that should be set to true if an error occurs. | 343 // The exit status that should be set to true if an error occurs. |
348 Ice::ErrorCode &ErrorStatus; | 344 Ice::ErrorCode &ErrorStatus; |
349 // The number of errors reported. | 345 // The number of errors reported. |
350 unsigned NumErrors = 0; | 346 unsigned NumErrors = 0; |
351 // The types associated with each type ID. | 347 // The types associated with each type ID. |
352 std::vector<ExtendedType> TypeIDValues; | 348 std::vector<ExtendedType> TypeIDValues; |
353 // The set of functions (prototype and defined). | 349 // The set of functions (prototype and defined). |
354 Ice::FunctionDeclarationList FunctionDeclarations; | 350 Ice::FunctionDeclarationList FunctionDeclarations; |
355 // The ID of the next possible defined function ID in FunctionDeclarations. | 351 // The ID of the next possible defined function ID in FunctionDeclarations. |
356 // FunctionDeclarations is filled first. It's the set of functions (either | 352 // FunctionDeclarations is filled first. It's the set of functions (either |
357 // defined or isproto). Then function definitions are encountered/parsed and | 353 // defined or isproto). Then function definitions are encountered/parsed and |
358 // NextDefiningFunctionID is incremented to track the next actually-defined | 354 // NextDefiningFunctionID is incremented to track the next actually-defined |
359 // function. | 355 // function. |
360 size_t NextDefiningFunctionID = 0; | 356 size_t NextDefiningFunctionID = 0; |
361 // The set of global variables. | 357 // The set of global variables. |
362 std::unique_ptr<Ice::VariableDeclarationList> VariableDeclarations; | 358 std::unique_ptr<Ice::VariableDeclarationList> VariableDeclarations; |
363 // Relocatable constants associated with global declarations. | 359 // Relocatable constants associated with global declarations. |
364 Ice::ConstantList ValueIDConstants; | 360 Ice::ConstantList ValueIDConstants; |
365 // Error recovery value to use when getFuncSigTypeByID fails. | 361 // Error recovery value to use when getFuncSigTypeByID fails. |
366 Ice::FuncSigType UndefinedFuncSigType; | 362 Ice::FuncSigType UndefinedFuncSigType; |
367 // The block parser currently being applied. Used for error | 363 // The block parser currently being applied. Used for error reporting. |
368 // reporting. | |
369 BlockParserBaseClass *BlockParser = nullptr; | 364 BlockParserBaseClass *BlockParser = nullptr; |
370 | 365 |
371 bool ParseBlock(unsigned BlockID) override; | 366 bool ParseBlock(unsigned BlockID) override; |
372 | 367 |
373 // Gets extended type associated with the given index, assuming the | 368 // Gets extended type associated with the given index, assuming the extended |
374 // extended type is of the WantedKind. Generates error message if | 369 // type is of the WantedKind. Generates error message if corresponding |
375 // corresponding extended type of WantedKind can't be found, and | 370 // extended type of WantedKind can't be found, and returns nullptr. |
376 // returns nullptr. | |
377 ExtendedType *getTypeByIDAsKind(NaClBcIndexSize_t ID, | 371 ExtendedType *getTypeByIDAsKind(NaClBcIndexSize_t ID, |
378 ExtendedType::TypeKind WantedKind) { | 372 ExtendedType::TypeKind WantedKind) { |
379 ExtendedType *Ty = nullptr; | 373 ExtendedType *Ty = nullptr; |
380 if (ID < TypeIDValues.size()) { | 374 if (ID < TypeIDValues.size()) { |
381 Ty = &TypeIDValues[ID]; | 375 Ty = &TypeIDValues[ID]; |
382 if (Ty->getKind() == WantedKind) | 376 if (Ty->getKind() == WantedKind) |
383 return Ty; | 377 return Ty; |
384 } | 378 } |
385 // Generate an error message and set ErrorStatus. | 379 // Generate an error message and set ErrorStatus. |
386 this->reportBadTypeIDAs(ID, Ty, WantedKind); | 380 this->reportBadTypeIDAs(ID, Ty, WantedKind); |
387 return nullptr; | 381 return nullptr; |
388 } | 382 } |
389 | 383 |
390 // Gives Decl a name if it doesn't already have one. Prefix and | 384 // Gives Decl a name if it doesn't already have one. Prefix and NameIndex are |
391 // NameIndex are used to generate the name. NameIndex is | 385 // used to generate the name. NameIndex is automatically incremented if a new |
392 // automatically incremented if a new name is created. DeclType is | 386 // name is created. DeclType is literal text describing the type of name |
393 // literal text describing the type of name being created. Also | 387 // being created. Also generates warning if created names may conflict with |
394 // generates warning if created names may conflict with named | 388 // named declarations. |
395 // declarations. | |
396 void installDeclarationName(Ice::GlobalDeclaration *Decl, | 389 void installDeclarationName(Ice::GlobalDeclaration *Decl, |
397 const Ice::IceString &Prefix, | 390 const Ice::IceString &Prefix, |
398 const char *DeclType, | 391 const char *DeclType, |
399 NaClBcIndexSize_t &NameIndex) { | 392 NaClBcIndexSize_t &NameIndex) { |
400 if (Decl->hasName()) { | 393 if (Decl->hasName()) { |
401 Translator.checkIfUnnamedNameSafe(Decl->getName(), DeclType, Prefix); | 394 Translator.checkIfUnnamedNameSafe(Decl->getName(), DeclType, Prefix); |
402 } else { | 395 } else { |
403 Decl->setName(Translator.createUnnamedName(Prefix, NameIndex)); | 396 Decl->setName(Translator.createUnnamedName(Prefix, NameIndex)); |
404 ++NameIndex; | 397 ++NameIndex; |
405 } | 398 } |
(...skipping 18 matching lines...) Expand all Loading... |
424 getTranslator().getFlags().getDefaultFunctionPrefix(); | 417 getTranslator().getFlags().getDefaultFunctionPrefix(); |
425 if (!FunctionPrefix.empty()) { | 418 if (!FunctionPrefix.empty()) { |
426 NaClBcIndexSize_t NameIndex = 0; | 419 NaClBcIndexSize_t NameIndex = 0; |
427 for (Ice::FunctionDeclaration *Func : FunctionDeclarations) { | 420 for (Ice::FunctionDeclaration *Func : FunctionDeclarations) { |
428 installDeclarationName(Func, FunctionPrefix, "function", NameIndex); | 421 installDeclarationName(Func, FunctionPrefix, "function", NameIndex); |
429 } | 422 } |
430 } | 423 } |
431 } | 424 } |
432 | 425 |
433 // Builds a constant symbol named Name, suppressing name mangling if | 426 // Builds a constant symbol named Name, suppressing name mangling if |
434 // SuppressMangling. IsExternal is true iff the symbol is external. | 427 // SuppressMangling. IsExternal is true iff the symbol is external. |
435 Ice::Constant *getConstantSym(const Ice::IceString &Name, | 428 Ice::Constant *getConstantSym(const Ice::IceString &Name, |
436 bool SuppressMangling, bool IsExternal) const { | 429 bool SuppressMangling, bool IsExternal) const { |
437 if (IsExternal) { | 430 if (IsExternal) { |
438 return getTranslator().getContext()->getConstantExternSym(Name); | 431 return getTranslator().getContext()->getConstantExternSym(Name); |
439 } else { | 432 } else { |
440 const Ice::RelocOffsetT Offset = 0; | 433 const Ice::RelocOffsetT Offset = 0; |
441 return getTranslator().getContext()->getConstantSym(Offset, Name, | 434 return getTranslator().getContext()->getConstantSym(Offset, Name, |
442 SuppressMangling); | 435 SuppressMangling); |
443 } | 436 } |
444 } | 437 } |
(...skipping 19 matching lines...) Expand all Loading... |
464 !Decl->hasInitializer()); | 457 !Decl->hasInitializer()); |
465 } | 458 } |
466 ValueIDConstants.push_back(C); | 459 ValueIDConstants.push_back(C); |
467 } | 460 } |
468 } | 461 } |
469 | 462 |
470 // Reports that type ID is undefined, or not of the WantedType. | 463 // Reports that type ID is undefined, or not of the WantedType. |
471 void reportBadTypeIDAs(NaClBcIndexSize_t ID, const ExtendedType *Ty, | 464 void reportBadTypeIDAs(NaClBcIndexSize_t ID, const ExtendedType *Ty, |
472 ExtendedType::TypeKind WantedType); | 465 ExtendedType::TypeKind WantedType); |
473 | 466 |
474 // Reports that there is no function declaration for ID. Returns an | 467 // Reports that there is no function declaration for ID. Returns an error |
475 // error recovery value to use. | 468 // recovery value to use. |
476 Ice::FunctionDeclaration *reportGetFunctionByIDError(NaClBcIndexSize_t ID); | 469 Ice::FunctionDeclaration *reportGetFunctionByIDError(NaClBcIndexSize_t ID); |
477 | 470 |
478 // Reports that there is not global variable declaration for | 471 // Reports that there is not global variable declaration for ID. Returns an |
479 // ID. Returns an error recovery value to use. | 472 // error recovery value to use. |
480 Ice::VariableDeclaration * | 473 Ice::VariableDeclaration * |
481 reportGetGlobalVariableByIDError(NaClBcIndexSize_t Index); | 474 reportGetGlobalVariableByIDError(NaClBcIndexSize_t Index); |
482 | 475 |
483 // Reports that there is no corresponding ICE type for LLVMTy, and | 476 // Reports that there is no corresponding ICE type for LLVMTy, and returns |
484 // returns Ice::IceType_void. | 477 // Ice::IceType_void. |
485 Ice::Type convertToIceTypeError(Type *LLVMTy); | 478 Ice::Type convertToIceTypeError(Type *LLVMTy); |
486 }; | 479 }; |
487 | 480 |
488 bool TopLevelParser::ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit, | 481 bool TopLevelParser::ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit, |
489 const std::string &Message) { | 482 const std::string &Message) { |
490 ErrorStatus.assign(Ice::EC_Bitcode); | 483 ErrorStatus.assign(Ice::EC_Bitcode); |
491 ++NumErrors; | 484 ++NumErrors; |
492 Ice::GlobalContext *Context = Translator.getContext(); | 485 Ice::GlobalContext *Context = Translator.getContext(); |
493 { // Lock while printing out error message. | 486 { // Lock while printing out error message. |
494 Ice::OstreamLocker L(Context); | 487 Ice::OstreamLocker L(Context); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
542 } | 535 } |
543 | 536 |
544 Ice::Type TopLevelParser::convertToIceTypeError(Type *LLVMTy) { | 537 Ice::Type TopLevelParser::convertToIceTypeError(Type *LLVMTy) { |
545 std::string Buffer; | 538 std::string Buffer; |
546 raw_string_ostream StrBuf(Buffer); | 539 raw_string_ostream StrBuf(Buffer); |
547 StrBuf << "Invalid LLVM type: " << *LLVMTy; | 540 StrBuf << "Invalid LLVM type: " << *LLVMTy; |
548 Error(StrBuf.str()); | 541 Error(StrBuf.str()); |
549 return Ice::IceType_void; | 542 return Ice::IceType_void; |
550 } | 543 } |
551 | 544 |
552 // Base class for parsing blocks within the bitcode file. Note: | 545 // Base class for parsing blocks within the bitcode file. Note: Because this is |
553 // Because this is the base class of block parsers, we generate error | 546 // the base class of block parsers, we generate error messages if ParseBlock or |
554 // messages if ParseBlock or ParseRecord is not overridden in derived | 547 // ParseRecord is not overridden in derived classes. |
555 // classes. | |
556 class BlockParserBaseClass : public NaClBitcodeParser { | 548 class BlockParserBaseClass : public NaClBitcodeParser { |
557 BlockParserBaseClass() = delete; | 549 BlockParserBaseClass() = delete; |
558 BlockParserBaseClass(const BlockParserBaseClass &) = delete; | 550 BlockParserBaseClass(const BlockParserBaseClass &) = delete; |
559 BlockParserBaseClass &operator=(const BlockParserBaseClass &) = delete; | 551 BlockParserBaseClass &operator=(const BlockParserBaseClass &) = delete; |
560 | 552 |
561 public: | 553 public: |
562 // Constructor for the top-level module block parser. | 554 // Constructor for the top-level module block parser. |
563 BlockParserBaseClass(unsigned BlockID, TopLevelParser *Context) | 555 BlockParserBaseClass(unsigned BlockID, TopLevelParser *Context) |
564 : NaClBitcodeParser(BlockID, Context), Context(Context) { | 556 : NaClBitcodeParser(BlockID, Context), Context(Context) { |
565 Context->setBlockParser(this); | 557 Context->setBlockParser(this); |
(...skipping 22 matching lines...) Expand all Loading... |
588 | 580 |
589 // Gets the translator associated with the bitcode parser. | 581 // Gets the translator associated with the bitcode parser. |
590 Ice::Translator &getTranslator() const { return Context->getTranslator(); } | 582 Ice::Translator &getTranslator() const { return Context->getTranslator(); } |
591 | 583 |
592 const Ice::ClFlags &getFlags() const { return getTranslator().getFlags(); } | 584 const Ice::ClFlags &getFlags() const { return getTranslator().getFlags(); } |
593 | 585 |
594 bool isIRGenerationDisabled() const { | 586 bool isIRGenerationDisabled() const { |
595 return getTranslator().getFlags().getDisableIRGeneration(); | 587 return getTranslator().getFlags().getDisableIRGeneration(); |
596 } | 588 } |
597 | 589 |
598 // Default implementation. Reports that block is unknown and skips | 590 // Default implementation. Reports that block is unknown and skips its |
599 // its contents. | 591 // contents. |
600 bool ParseBlock(unsigned BlockID) override; | 592 bool ParseBlock(unsigned BlockID) override; |
601 | 593 |
602 // Default implementation. Reports that the record is not | 594 // Default implementation. Reports that the record is not understood. |
603 // understood. | |
604 void ProcessRecord() override; | 595 void ProcessRecord() override; |
605 | 596 |
606 // Checks if the size of the record is Size. Return true if valid. | 597 // Checks if the size of the record is Size. Return true if valid. Otherwise |
607 // Otherwise generates an error and returns false. | 598 // generates an error and returns false. |
608 bool isValidRecordSize(size_t Size, const char *RecordName) { | 599 bool isValidRecordSize(size_t Size, const char *RecordName) { |
609 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); | 600 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); |
610 if (Values.size() == Size) | 601 if (Values.size() == Size) |
611 return true; | 602 return true; |
612 reportRecordSizeError(Size, RecordName, nullptr); | 603 reportRecordSizeError(Size, RecordName, nullptr); |
613 return false; | 604 return false; |
614 } | 605 } |
615 | 606 |
616 // Checks if the size of the record is at least as large as the | 607 // Checks if the size of the record is at least as large as the LowerLimit. |
617 // LowerLimit. Returns true if valid. Otherwise generates an error | 608 // Returns true if valid. Otherwise generates an error and returns false. |
618 // and returns false. | |
619 bool isValidRecordSizeAtLeast(size_t LowerLimit, const char *RecordName) { | 609 bool isValidRecordSizeAtLeast(size_t LowerLimit, const char *RecordName) { |
620 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); | 610 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); |
621 if (Values.size() >= LowerLimit) | 611 if (Values.size() >= LowerLimit) |
622 return true; | 612 return true; |
623 reportRecordSizeError(LowerLimit, RecordName, "at least"); | 613 reportRecordSizeError(LowerLimit, RecordName, "at least"); |
624 return false; | 614 return false; |
625 } | 615 } |
626 | 616 |
627 // Checks if the size of the record is no larger than the | 617 // Checks if the size of the record is no larger than the |
628 // UpperLimit. Returns true if valid. Otherwise generates an error | 618 // UpperLimit. Returns true if valid. Otherwise generates an error and |
629 // and returns false. | 619 // returns false. |
630 bool isValidRecordSizeAtMost(size_t UpperLimit, const char *RecordName) { | 620 bool isValidRecordSizeAtMost(size_t UpperLimit, const char *RecordName) { |
631 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); | 621 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); |
632 if (Values.size() <= UpperLimit) | 622 if (Values.size() <= UpperLimit) |
633 return true; | 623 return true; |
634 reportRecordSizeError(UpperLimit, RecordName, "no more than"); | 624 reportRecordSizeError(UpperLimit, RecordName, "no more than"); |
635 return false; | 625 return false; |
636 } | 626 } |
637 | 627 |
638 // Checks if the size of the record is at least as large as the | 628 // Checks if the size of the record is at least as large as the LowerLimit, |
639 // LowerLimit, and no larger than the UpperLimit. Returns true if | 629 // and no larger than the UpperLimit. Returns true if valid. Otherwise |
640 // valid. Otherwise generates an error and returns false. | 630 // generates an error and returns false. |
641 bool isValidRecordSizeInRange(size_t LowerLimit, size_t UpperLimit, | 631 bool isValidRecordSizeInRange(size_t LowerLimit, size_t UpperLimit, |
642 const char *RecordName) { | 632 const char *RecordName) { |
643 return isValidRecordSizeAtLeast(LowerLimit, RecordName) || | 633 return isValidRecordSizeAtLeast(LowerLimit, RecordName) || |
644 isValidRecordSizeAtMost(UpperLimit, RecordName); | 634 isValidRecordSizeAtMost(UpperLimit, RecordName); |
645 } | 635 } |
646 | 636 |
647 private: | 637 private: |
648 /// Generates a record size error. ExpectedSize is the number | 638 /// Generates a record size error. ExpectedSize is the number of elements |
649 /// of elements expected. RecordName is the name of the kind of | 639 /// expected. RecordName is the name of the kind of record that has incorrect |
650 /// record that has incorrect size. ContextMessage (if not nullptr) | 640 /// size. ContextMessage (if not nullptr) is appended to "record expects" to |
651 /// is appended to "record expects" to describe how ExpectedSize | 641 /// describe how ExpectedSize should be interpreted. |
652 /// should be interpreted. | |
653 void reportRecordSizeError(size_t ExpectedSize, const char *RecordName, | 642 void reportRecordSizeError(size_t ExpectedSize, const char *RecordName, |
654 const char *ContextMessage); | 643 const char *ContextMessage); |
655 }; | 644 }; |
656 | 645 |
657 bool TopLevelParser::blockError(const std::string &Message) { | 646 bool TopLevelParser::blockError(const std::string &Message) { |
658 if (BlockParser) | 647 if (BlockParser) |
659 return BlockParser->Error(Message); | 648 return BlockParser->Error(Message); |
660 else | 649 else |
661 return Error(Message); | 650 return Error(Message); |
662 } | 651 } |
663 | 652 |
664 // Generates an error Message with the bit address prefixed to it. | 653 // Generates an error Message with the bit address prefixed to it. |
665 bool BlockParserBaseClass::ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit, | 654 bool BlockParserBaseClass::ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit, |
666 const std::string &Message) { | 655 const std::string &Message) { |
667 std::string Buffer; | 656 std::string Buffer; |
668 raw_string_ostream StrBuf(Buffer); | 657 raw_string_ostream StrBuf(Buffer); |
669 // Note: If dump routines have been turned off, the error messages | 658 // Note: If dump routines have been turned off, the error messages will not |
670 // will not be readable. Hence, replace with simple error. We also | 659 // be readable. Hence, replace with simple error. We also use the simple form |
671 // use the simple form for unit tests. | 660 // for unit tests. |
672 if (getFlags().getGenerateUnitTestMessages()) { | 661 if (getFlags().getGenerateUnitTestMessages()) { |
673 StrBuf << "Invalid " << getBlockName() << " record: <" << Record.GetCode(); | 662 StrBuf << "Invalid " << getBlockName() << " record: <" << Record.GetCode(); |
674 for (const uint64_t Val : Record.GetValues()) { | 663 for (const uint64_t Val : Record.GetValues()) { |
675 StrBuf << " " << Val; | 664 StrBuf << " " << Val; |
676 } | 665 } |
677 StrBuf << ">"; | 666 StrBuf << ">"; |
678 } else { | 667 } else { |
679 StrBuf << Message; | 668 StrBuf << Message; |
680 } | 669 } |
681 return Context->ErrorAt(Level, Bit, StrBuf.str()); | 670 return Context->ErrorAt(Level, Bit, StrBuf.str()); |
(...skipping 11 matching lines...) Expand all Loading... |
693 if (ContextMessage) | 682 if (ContextMessage) |
694 StrBuf << " " << ContextMessage; | 683 StrBuf << " " << ContextMessage; |
695 StrBuf << " " << ExpectedSize << " argument"; | 684 StrBuf << " " << ExpectedSize << " argument"; |
696 if (ExpectedSize > 1) | 685 if (ExpectedSize > 1) |
697 StrBuf << "s"; | 686 StrBuf << "s"; |
698 StrBuf << ". Found: " << Record.GetValues().size(); | 687 StrBuf << ". Found: " << Record.GetValues().size(); |
699 Error(StrBuf.str()); | 688 Error(StrBuf.str()); |
700 } | 689 } |
701 | 690 |
702 bool BlockParserBaseClass::ParseBlock(unsigned BlockID) { | 691 bool BlockParserBaseClass::ParseBlock(unsigned BlockID) { |
703 // If called, derived class doesn't know how to handle block. | 692 // If called, derived class doesn't know how to handle block. Report error |
704 // Report error and skip. | 693 // and skip. |
705 std::string Buffer; | 694 std::string Buffer; |
706 raw_string_ostream StrBuf(Buffer); | 695 raw_string_ostream StrBuf(Buffer); |
707 StrBuf << "Don't know how to parse block id: " << BlockID; | 696 StrBuf << "Don't know how to parse block id: " << BlockID; |
708 Error(StrBuf.str()); | 697 Error(StrBuf.str()); |
709 SkipBlock(); | 698 SkipBlock(); |
710 return false; | 699 return false; |
711 } | 700 } |
712 | 701 |
713 void BlockParserBaseClass::ProcessRecord() { | 702 void BlockParserBaseClass::ProcessRecord() { |
714 // If called, derived class doesn't know how to handle. | 703 // If called, derived class doesn't know how to handle. |
(...skipping 20 matching lines...) Expand all Loading... |
735 std::string Buffer; | 724 std::string Buffer; |
736 raw_string_ostream StrBuf(Buffer); | 725 raw_string_ostream StrBuf(Buffer); |
737 StrBuf << "Types block expected " << ExpectedNumTypes | 726 StrBuf << "Types block expected " << ExpectedNumTypes |
738 << " types but found: " << NextTypeId; | 727 << " types but found: " << NextTypeId; |
739 Error(StrBuf.str()); | 728 Error(StrBuf.str()); |
740 } | 729 } |
741 } | 730 } |
742 | 731 |
743 private: | 732 private: |
744 Ice::TimerMarker Timer; | 733 Ice::TimerMarker Timer; |
745 // The type ID that will be associated with the next type defining | 734 // The type ID that will be associated with the next type defining record in |
746 // record in the types block. | 735 // the types block. |
747 NaClBcIndexSize_t NextTypeId = 0; | 736 NaClBcIndexSize_t NextTypeId = 0; |
748 | 737 |
749 // The expected number of types, based on record TYPE_CODE_NUMENTRY. | 738 // The expected number of types, based on record TYPE_CODE_NUMENTRY. |
750 NaClBcIndexSize_t ExpectedNumTypes = 0; | 739 NaClBcIndexSize_t ExpectedNumTypes = 0; |
751 | 740 |
752 void ProcessRecord() override; | 741 void ProcessRecord() override; |
753 | 742 |
754 const char *getBlockName() const override { return "type"; } | 743 const char *getBlockName() const override { return "type"; } |
755 | 744 |
756 void setNextTypeIDAsSimpleType(Ice::Type Ty) { | 745 void setNextTypeIDAsSimpleType(Ice::Type Ty) { |
757 Context->getTypeByIDForDefining(NextTypeId++)->setAsSimpleType(Ty); | 746 Context->getTypeByIDForDefining(NextTypeId++)->setAsSimpleType(Ty); |
758 } | 747 } |
759 }; | 748 }; |
760 | 749 |
761 void TypesParser::ProcessRecord() { | 750 void TypesParser::ProcessRecord() { |
762 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); | 751 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); |
763 switch (Record.GetCode()) { | 752 switch (Record.GetCode()) { |
764 case naclbitc::TYPE_CODE_NUMENTRY: { | 753 case naclbitc::TYPE_CODE_NUMENTRY: { |
765 // NUMENTRY: [numentries] | 754 // NUMENTRY: [numentries] |
766 if (!isValidRecordSize(1, "count")) | 755 if (!isValidRecordSize(1, "count")) |
767 return; | 756 return; |
768 uint64_t Size = Values[0]; | 757 uint64_t Size = Values[0]; |
769 if (Size > NaClBcIndexSize_t_Max) { | 758 if (Size > NaClBcIndexSize_t_Max) { |
770 std::string Buffer; | 759 std::string Buffer; |
771 raw_string_ostream StrBuf(Buffer); | 760 raw_string_ostream StrBuf(Buffer); |
772 StrBuf << "Size to big for count record: " << Size; | 761 StrBuf << "Size to big for count record: " << Size; |
773 Error(StrBuf.str()); | 762 Error(StrBuf.str()); |
774 ExpectedNumTypes = NaClBcIndexSize_t_Max; | 763 ExpectedNumTypes = NaClBcIndexSize_t_Max; |
775 } | 764 } |
776 // The code double checks that Expected size and the actual size | 765 // The code double checks that Expected size and the actual size at the end |
777 // at the end of the block. To reduce allocations we preallocate | 766 // of the block. To reduce allocations we preallocate the space. |
778 // the space. | |
779 // | 767 // |
780 // However, if the number is large, we suspect that the number | 768 // However, if the number is large, we suspect that the number is |
781 // is (possibly) incorrect. In that case, we preallocate a | 769 // (possibly) incorrect. In that case, we preallocate a smaller space. |
782 // smaller space. | |
783 constexpr uint64_t DefaultLargeResizeValue = 1000000; | 770 constexpr uint64_t DefaultLargeResizeValue = 1000000; |
784 Context->resizeTypeIDValues(std::min(Size, DefaultLargeResizeValue)); | 771 Context->resizeTypeIDValues(std::min(Size, DefaultLargeResizeValue)); |
785 ExpectedNumTypes = Size; | 772 ExpectedNumTypes = Size; |
786 return; | 773 return; |
787 } | 774 } |
788 case naclbitc::TYPE_CODE_VOID: | 775 case naclbitc::TYPE_CODE_VOID: |
789 // VOID | 776 // VOID |
790 if (!isValidRecordSize(0, "void")) | 777 if (!isValidRecordSize(0, "void")) |
791 return; | 778 return; |
792 setNextTypeIDAsSimpleType(Ice::IceType_void); | 779 setNextTypeIDAsSimpleType(Ice::IceType_void); |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
895 // FUNCTION: [vararg, retty, paramty x N] | 882 // FUNCTION: [vararg, retty, paramty x N] |
896 if (!isValidRecordSizeAtLeast(2, "signature")) | 883 if (!isValidRecordSizeAtLeast(2, "signature")) |
897 return; | 884 return; |
898 if (Values[0]) | 885 if (Values[0]) |
899 Error("Function type can't define varargs"); | 886 Error("Function type can't define varargs"); |
900 ExtendedType *Ty = Context->getTypeByIDForDefining(NextTypeId++); | 887 ExtendedType *Ty = Context->getTypeByIDForDefining(NextTypeId++); |
901 Ty->setAsFunctionType(); | 888 Ty->setAsFunctionType(); |
902 FuncSigExtendedType *FuncTy = cast<FuncSigExtendedType>(Ty); | 889 FuncSigExtendedType *FuncTy = cast<FuncSigExtendedType>(Ty); |
903 FuncTy->setReturnType(Context->getSimpleTypeByID(Values[1])); | 890 FuncTy->setReturnType(Context->getSimpleTypeByID(Values[1])); |
904 for (size_t i = 2, e = Values.size(); i != e; ++i) { | 891 for (size_t i = 2, e = Values.size(); i != e; ++i) { |
905 // Check that type void not used as argument type. | 892 // Check that type void not used as argument type. Note: PNaCl |
906 // Note: PNaCl restrictions can't be checked until we | 893 // restrictions can't be checked until we know the name, because we have |
907 // know the name, because we have to check for intrinsic signatures. | 894 // to check for intrinsic signatures. |
908 Ice::Type ArgTy = Context->getSimpleTypeByID(Values[i]); | 895 Ice::Type ArgTy = Context->getSimpleTypeByID(Values[i]); |
909 if (ArgTy == Ice::IceType_void) { | 896 if (ArgTy == Ice::IceType_void) { |
910 std::string Buffer; | 897 std::string Buffer; |
911 raw_string_ostream StrBuf(Buffer); | 898 raw_string_ostream StrBuf(Buffer); |
912 StrBuf << "Type for parameter " << (i - 1) | 899 StrBuf << "Type for parameter " << (i - 1) |
913 << " not valid. Found: " << ArgTy; | 900 << " not valid. Found: " << ArgTy; |
914 ArgTy = Ice::IceType_i32; | 901 ArgTy = Ice::IceType_i32; |
915 } | 902 } |
916 FuncTy->appendArgType(ArgTy); | 903 FuncTy->appendArgType(ArgTy); |
917 } | 904 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
949 std::unordered_map<NaClBcIndexSize_t, Ice::VariableDeclaration *>; | 936 std::unordered_map<NaClBcIndexSize_t, Ice::VariableDeclaration *>; |
950 | 937 |
951 Ice::TimerMarker Timer; | 938 Ice::TimerMarker Timer; |
952 | 939 |
953 // Holds global variables generated/referenced in the global variables block. | 940 // Holds global variables generated/referenced in the global variables block. |
954 GlobalVarsMapType GlobalVarsMap; | 941 GlobalVarsMapType GlobalVarsMap; |
955 | 942 |
956 // Holds the number of defined function IDs. | 943 // Holds the number of defined function IDs. |
957 NaClBcIndexSize_t NumFunctionIDs; | 944 NaClBcIndexSize_t NumFunctionIDs; |
958 | 945 |
959 // Holds the specified number of global variables by the count record in | 946 // Holds the specified number of global variables by the count record in the |
960 // the global variables block. | 947 // global variables block. |
961 NaClBcIndexSize_t SpecifiedNumberVars = 0; | 948 NaClBcIndexSize_t SpecifiedNumberVars = 0; |
962 | 949 |
963 // Keeps track of how many initializers are expected for the global variable | 950 // Keeps track of how many initializers are expected for the global variable |
964 // declaration being built. | 951 // declaration being built. |
965 NaClBcIndexSize_t InitializersNeeded = 0; | 952 NaClBcIndexSize_t InitializersNeeded = 0; |
966 | 953 |
967 // The index of the next global variable declaration. | 954 // The index of the next global variable declaration. |
968 NaClBcIndexSize_t NextGlobalID = 0; | 955 NaClBcIndexSize_t NextGlobalID = 0; |
969 | 956 |
970 // Dummy global variable declaration to guarantee CurGlobalVar is | 957 // Dummy global variable declaration to guarantee CurGlobalVar is always |
971 // always defined (allowing code to not need to check if | 958 // defined (allowing code to not need to check if CurGlobalVar is nullptr). |
972 // CurGlobalVar is nullptr). | |
973 Ice::VariableDeclaration *DummyGlobalVar; | 959 Ice::VariableDeclaration *DummyGlobalVar; |
974 | 960 |
975 // Holds the current global variable declaration being built. | 961 // Holds the current global variable declaration being built. |
976 Ice::VariableDeclaration *CurGlobalVar; | 962 Ice::VariableDeclaration *CurGlobalVar; |
977 | 963 |
978 // Returns the global variable associated with the given Index. | 964 // Returns the global variable associated with the given Index. |
979 Ice::VariableDeclaration *getGlobalVarByID(NaClBcIndexSize_t Index) { | 965 Ice::VariableDeclaration *getGlobalVarByID(NaClBcIndexSize_t Index) { |
980 Ice::VariableDeclaration *&Decl = GlobalVarsMap[Index]; | 966 Ice::VariableDeclaration *&Decl = GlobalVarsMap[Index]; |
981 if (Decl == nullptr) | 967 if (Decl == nullptr) |
982 Decl = Ice::VariableDeclaration::create(getTranslator().getContext()); | 968 Decl = Ice::VariableDeclaration::create(getTranslator().getContext()); |
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1223 bool convertFunction() { | 1209 bool convertFunction() { |
1224 const Ice::TimerStackIdT StackID = Ice::GlobalContext::TSK_Funcs; | 1210 const Ice::TimerStackIdT StackID = Ice::GlobalContext::TSK_Funcs; |
1225 Ice::TimerIdT TimerID = 0; | 1211 Ice::TimerIdT TimerID = 0; |
1226 const bool TimeThisFunction = getFlags().getTimeEachFunction(); | 1212 const bool TimeThisFunction = getFlags().getTimeEachFunction(); |
1227 if (TimeThisFunction) { | 1213 if (TimeThisFunction) { |
1228 TimerID = getTranslator().getContext()->getTimerID(StackID, | 1214 TimerID = getTranslator().getContext()->getTimerID(StackID, |
1229 FuncDecl->getName()); | 1215 FuncDecl->getName()); |
1230 getTranslator().getContext()->pushTimer(TimerID, StackID); | 1216 getTranslator().getContext()->pushTimer(TimerID, StackID); |
1231 } | 1217 } |
1232 | 1218 |
1233 // Note: The Cfg is created, even when IR generation is disabled. This | 1219 // Note: The Cfg is created, even when IR generation is disabled. This is |
1234 // is done to install a CfgLocalAllocator for various internal containers. | 1220 // done to install a CfgLocalAllocator for various internal containers. |
1235 Func = Ice::Cfg::create(getTranslator().getContext(), | 1221 Func = Ice::Cfg::create(getTranslator().getContext(), |
1236 getTranslator().getNextSequenceNumber()); | 1222 getTranslator().getNextSequenceNumber()); |
1237 Ice::Cfg::setCurrentCfg(Func.get()); | 1223 Ice::Cfg::setCurrentCfg(Func.get()); |
1238 | 1224 |
1239 // TODO(kschimpf) Clean up API to add a function signature to | 1225 // TODO(kschimpf) Clean up API to add a function signature to a CFG. |
1240 // a CFG. | |
1241 const Ice::FuncSigType &Signature = FuncDecl->getSignature(); | 1226 const Ice::FuncSigType &Signature = FuncDecl->getSignature(); |
1242 if (isIRGenerationDisabled()) { | 1227 if (isIRGenerationDisabled()) { |
1243 CurrentNode = nullptr; | 1228 CurrentNode = nullptr; |
1244 for (Ice::Type ArgType : Signature.getArgList()) { | 1229 for (Ice::Type ArgType : Signature.getArgList()) { |
1245 (void)ArgType; | 1230 (void)ArgType; |
1246 setNextLocalInstIndex(nullptr); | 1231 setNextLocalInstIndex(nullptr); |
1247 } | 1232 } |
1248 } else { | 1233 } else { |
1249 Func->setFunctionName(FuncDecl->getName()); | 1234 Func->setFunctionName(FuncDecl->getName()); |
1250 Func->setReturnType(Signature.getReturnType()); | 1235 Func->setReturnType(Signature.getReturnType()); |
1251 Func->setInternal(FuncDecl->getLinkage() == GlobalValue::InternalLinkage); | 1236 Func->setInternal(FuncDecl->getLinkage() == GlobalValue::InternalLinkage); |
1252 CurrentNode = installNextBasicBlock(); | 1237 CurrentNode = installNextBasicBlock(); |
1253 Func->setEntryNode(CurrentNode); | 1238 Func->setEntryNode(CurrentNode); |
1254 for (Ice::Type ArgType : Signature.getArgList()) { | 1239 for (Ice::Type ArgType : Signature.getArgList()) { |
1255 Func->addArg(getNextInstVar(ArgType)); | 1240 Func->addArg(getNextInstVar(ArgType)); |
1256 } | 1241 } |
1257 } | 1242 } |
1258 bool ParserResult = ParseThisBlock(); | 1243 bool ParserResult = ParseThisBlock(); |
1259 | 1244 |
1260 // Temporarily end per-function timing, which will be resumed by | 1245 // Temporarily end per-function timing, which will be resumed by the |
1261 // the translator function. This is because translation may be | 1246 // translator function. This is because translation may be done |
1262 // done asynchronously in a separate thread. | 1247 // asynchronously in a separate thread. |
1263 if (TimeThisFunction) | 1248 if (TimeThisFunction) |
1264 getTranslator().getContext()->popTimer(TimerID, StackID); | 1249 getTranslator().getContext()->popTimer(TimerID, StackID); |
1265 | 1250 |
1266 Ice::Cfg::setCurrentCfg(nullptr); | 1251 Ice::Cfg::setCurrentCfg(nullptr); |
1267 // Note: Once any errors have been found, we turn off all | 1252 // Note: Once any errors have been found, we turn off all translation of |
1268 // translation of all remaining functions. This allows successive | 1253 // all remaining functions. This allows successive parsing errors to be |
1269 // parsing errors to be reported, without adding extra checks to | 1254 // reported, without adding extra checks to the translator for such parsing |
1270 // the translator for such parsing errors. | 1255 // errors. |
1271 if (Context->getNumErrors() == 0 && Func) { | 1256 if (Context->getNumErrors() == 0 && Func) { |
1272 getTranslator().translateFcn(std::move(Func)); | 1257 getTranslator().translateFcn(std::move(Func)); |
1273 // The translator now has ownership of Func. | 1258 // The translator now has ownership of Func. |
1274 } else { | 1259 } else { |
1275 Func.reset(); | 1260 Func.reset(); |
1276 } | 1261 } |
1277 | 1262 |
1278 return ParserResult; | 1263 return ParserResult; |
1279 } | 1264 } |
1280 | 1265 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1325 // The number of basic blocks declared for the function block. | 1310 // The number of basic blocks declared for the function block. |
1326 NaClBcIndexSize_t DeclaredNumberBbs = 0; | 1311 NaClBcIndexSize_t DeclaredNumberBbs = 0; |
1327 // The basic block being built. | 1312 // The basic block being built. |
1328 Ice::CfgNode *CurrentNode = nullptr; | 1313 Ice::CfgNode *CurrentNode = nullptr; |
1329 // The ID for the function. | 1314 // The ID for the function. |
1330 NaClBcIndexSize_t FcnId; | 1315 NaClBcIndexSize_t FcnId; |
1331 // The corresponding function declaration. | 1316 // The corresponding function declaration. |
1332 Ice::FunctionDeclaration *FuncDecl; | 1317 Ice::FunctionDeclaration *FuncDecl; |
1333 // Holds the dividing point between local and global absolute value indices. | 1318 // Holds the dividing point between local and global absolute value indices. |
1334 size_t CachedNumGlobalValueIDs; | 1319 size_t CachedNumGlobalValueIDs; |
1335 // Holds operands local to the function block, based on indices | 1320 // Holds operands local to the function block, based on indices defined in |
1336 // defined in the bitcode file. | 1321 // the bitcode file. |
1337 Ice::OperandList LocalOperands; | 1322 Ice::OperandList LocalOperands; |
1338 // Holds the index within LocalOperands corresponding to the next | 1323 // Holds the index within LocalOperands corresponding to the next instruction |
1339 // instruction that generates a value. | 1324 // that generates a value. |
1340 NaClBcIndexSize_t NextLocalInstIndex; | 1325 NaClBcIndexSize_t NextLocalInstIndex; |
1341 // True if the last processed instruction was a terminating | 1326 // True if the last processed instruction was a terminating instruction. |
1342 // instruction. | |
1343 bool InstIsTerminating = false; | 1327 bool InstIsTerminating = false; |
1344 // Upper limit of alignment power allowed by LLVM | 1328 // Upper limit of alignment power allowed by LLVM |
1345 static const uint32_t AlignPowerLimit = 29; | 1329 static const uint32_t AlignPowerLimit = 29; |
1346 | 1330 |
1347 // Extracts the corresponding Alignment to use, given the AlignPower | 1331 // Extracts the corresponding Alignment to use, given the AlignPower (i.e. |
1348 // (i.e. 2**(AlignPower-1), or 0 if AlignPower == 0). InstName is the | 1332 // 2**(AlignPower-1), or 0 if AlignPower == 0). InstName is the name of the |
1349 // name of the instruction the alignment appears in. | 1333 // instruction the alignment appears in. |
1350 void extractAlignment(const char *InstName, uint32_t AlignPower, | 1334 void extractAlignment(const char *InstName, uint32_t AlignPower, |
1351 uint32_t &Alignment) { | 1335 uint32_t &Alignment) { |
1352 if (AlignPower <= AlignPowerLimit + 1) { | 1336 if (AlignPower <= AlignPowerLimit + 1) { |
1353 Alignment = (1 << AlignPower) >> 1; | 1337 Alignment = (1 << AlignPower) >> 1; |
1354 return; | 1338 return; |
1355 } | 1339 } |
1356 std::string Buffer; | 1340 std::string Buffer; |
1357 raw_string_ostream StrBuf(Buffer); | 1341 raw_string_ostream StrBuf(Buffer); |
1358 StrBuf << InstName << " alignment greater than 2**" << AlignPowerLimit | 1342 StrBuf << InstName << " alignment greater than 2**" << AlignPowerLimit |
1359 << ". Found: 2**" << (AlignPower - 1); | 1343 << ". Found: 2**" << (AlignPower - 1); |
(...skipping 29 matching lines...) Expand all Loading... |
1389 std::string Buffer; | 1373 std::string Buffer; |
1390 raw_string_ostream StrBuf(Buffer); | 1374 raw_string_ostream StrBuf(Buffer); |
1391 StrBuf << "Reference to basic block " << Index | 1375 StrBuf << "Reference to basic block " << Index |
1392 << " not found. Must be less than " << Func->getNumNodes(); | 1376 << " not found. Must be less than " << Func->getNumNodes(); |
1393 Error(StrBuf.str()); | 1377 Error(StrBuf.str()); |
1394 Index = 0; | 1378 Index = 0; |
1395 } | 1379 } |
1396 return Func->getNodes()[Index]; | 1380 return Func->getNodes()[Index]; |
1397 } | 1381 } |
1398 | 1382 |
1399 // Returns the Index-th basic block in the list of basic blocks. | 1383 // Returns the Index-th basic block in the list of basic blocks. Assumes |
1400 // Assumes Index corresponds to a branch instruction. Hence, if | 1384 // Index corresponds to a branch instruction. Hence, if the branch references |
1401 // the branch references the entry block, it also generates a | 1385 // the entry block, it also generates a corresponding error. |
1402 // corresponding error. | |
1403 Ice::CfgNode *getBranchBasicBlock(NaClBcIndexSize_t Index) { | 1386 Ice::CfgNode *getBranchBasicBlock(NaClBcIndexSize_t Index) { |
1404 assert(!isIRGenerationDisabled()); | 1387 assert(!isIRGenerationDisabled()); |
1405 if (Index == 0) { | 1388 if (Index == 0) { |
1406 Error("Branch to entry block not allowed"); | 1389 Error("Branch to entry block not allowed"); |
1407 } | 1390 } |
1408 return getBasicBlock(Index); | 1391 return getBasicBlock(Index); |
1409 } | 1392 } |
1410 | 1393 |
1411 // Generate an instruction variable with type Ty. | 1394 // Generate an instruction variable with type Ty. |
1412 Ice::Variable *createInstVar(Ice::Type Ty) { | 1395 Ice::Variable *createInstVar(Ice::Type Ty) { |
(...skipping 28 matching lines...) Expand all Loading... |
1441 Error(StrBuf.str()); | 1424 Error(StrBuf.str()); |
1442 ++NextLocalInstIndex; | 1425 ++NextLocalInstIndex; |
1443 return createInstVar(Ty); | 1426 return createInstVar(Ty); |
1444 } | 1427 } |
1445 } | 1428 } |
1446 Ice::Variable *Var = createInstVar(Ty); | 1429 Ice::Variable *Var = createInstVar(Ty); |
1447 setOperand(NextLocalInstIndex++, Var); | 1430 setOperand(NextLocalInstIndex++, Var); |
1448 return Var; | 1431 return Var; |
1449 } | 1432 } |
1450 | 1433 |
1451 // Converts a relative index (wrt to BaseIndex) to an absolute value | 1434 // Converts a relative index (wrt to BaseIndex) to an absolute value index. |
1452 // index. | |
1453 NaClBcIndexSize_t convertRelativeToAbsIndex(NaClRelBcIndexSize_t Id, | 1435 NaClBcIndexSize_t convertRelativeToAbsIndex(NaClRelBcIndexSize_t Id, |
1454 NaClRelBcIndexSize_t BaseIndex) { | 1436 NaClRelBcIndexSize_t BaseIndex) { |
1455 if (BaseIndex < Id) { | 1437 if (BaseIndex < Id) { |
1456 std::string Buffer; | 1438 std::string Buffer; |
1457 raw_string_ostream StrBuf(Buffer); | 1439 raw_string_ostream StrBuf(Buffer); |
1458 StrBuf << "Invalid relative value id: " << Id | 1440 StrBuf << "Invalid relative value id: " << Id |
1459 << " (must be <= " << BaseIndex << ")"; | 1441 << " (must be <= " << BaseIndex << ")"; |
1460 Error(StrBuf.str()); | 1442 Error(StrBuf.str()); |
1461 return 0; | 1443 return 0; |
1462 } | 1444 } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1501 | 1483 |
1502 // Error has occurred. | 1484 // Error has occurred. |
1503 std::string Buffer; | 1485 std::string Buffer; |
1504 raw_string_ostream StrBuf(Buffer); | 1486 raw_string_ostream StrBuf(Buffer); |
1505 StrBuf << "Multiple definitions for index " << Index << ": " << *Op | 1487 StrBuf << "Multiple definitions for index " << Index << ": " << *Op |
1506 << " and " << *OldOp; | 1488 << " and " << *OldOp; |
1507 Error(StrBuf.str()); | 1489 Error(StrBuf.str()); |
1508 LocalOperands[LocalIndex] = Op; | 1490 LocalOperands[LocalIndex] = Op; |
1509 } | 1491 } |
1510 | 1492 |
1511 // Returns the relative operand (wrt to BaseIndex) referenced by | 1493 // Returns the relative operand (wrt to BaseIndex) referenced by the given |
1512 // the given value Index. | 1494 // value Index. |
1513 Ice::Operand *getRelativeOperand(NaClBcIndexSize_t Index, | 1495 Ice::Operand *getRelativeOperand(NaClBcIndexSize_t Index, |
1514 NaClBcIndexSize_t BaseIndex) { | 1496 NaClBcIndexSize_t BaseIndex) { |
1515 return getOperand(convertRelativeToAbsIndex(Index, BaseIndex)); | 1497 return getOperand(convertRelativeToAbsIndex(Index, BaseIndex)); |
1516 } | 1498 } |
1517 | 1499 |
1518 // Returns the absolute index of the next value generating instruction. | 1500 // Returns the absolute index of the next value generating instruction. |
1519 NaClBcIndexSize_t getNextInstIndex() const { return NextLocalInstIndex; } | 1501 NaClBcIndexSize_t getNextInstIndex() const { return NextLocalInstIndex; } |
1520 | 1502 |
1521 // Generates type error message for binary operator Op | 1503 // Generates type error message for binary operator Op operating on Type |
1522 // operating on Type OpTy. | 1504 // OpTy. |
1523 void reportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy); | 1505 void reportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy); |
1524 | 1506 |
1525 // Validates if integer logical Op, for type OpTy, is valid. | 1507 // Validates if integer logical Op, for type OpTy, is valid. Returns true if |
1526 // Returns true if valid. Otherwise generates error message and | 1508 // valid. Otherwise generates error message and returns false. |
1527 // returns false. | |
1528 bool isValidIntegerLogicalOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) { | 1509 bool isValidIntegerLogicalOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) { |
1529 if (Ice::isIntegerType(OpTy)) | 1510 if (Ice::isIntegerType(OpTy)) |
1530 return true; | 1511 return true; |
1531 reportInvalidBinaryOp(Op, OpTy); | 1512 reportInvalidBinaryOp(Op, OpTy); |
1532 return false; | 1513 return false; |
1533 } | 1514 } |
1534 | 1515 |
1535 // Validates if integer (or vector of integers) arithmetic Op, for type | 1516 // Validates if integer (or vector of integers) arithmetic Op, for type OpTy, |
1536 // OpTy, is valid. Returns true if valid. Otherwise generates | 1517 // is valid. Returns true if valid. Otherwise generates error message and |
1537 // error message and returns false. | 1518 // returns false. |
1538 bool isValidIntegerArithOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) { | 1519 bool isValidIntegerArithOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) { |
1539 if (Ice::isIntegerArithmeticType(OpTy)) | 1520 if (Ice::isIntegerArithmeticType(OpTy)) |
1540 return true; | 1521 return true; |
1541 reportInvalidBinaryOp(Op, OpTy); | 1522 reportInvalidBinaryOp(Op, OpTy); |
1542 return false; | 1523 return false; |
1543 } | 1524 } |
1544 | 1525 |
1545 // Checks if floating arithmetic Op, for type OpTy, is valid. | 1526 // Checks if floating arithmetic Op, for type OpTy, is valid. Returns true if |
1546 // Returns true if valid. Otherwise generates an error message and | 1527 // valid. Otherwise generates an error message and returns false; |
1547 // returns false; | |
1548 bool isValidFloatingArithOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) { | 1528 bool isValidFloatingArithOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) { |
1549 if (Ice::isFloatingType(OpTy)) | 1529 if (Ice::isFloatingType(OpTy)) |
1550 return true; | 1530 return true; |
1551 reportInvalidBinaryOp(Op, OpTy); | 1531 reportInvalidBinaryOp(Op, OpTy); |
1552 return false; | 1532 return false; |
1553 } | 1533 } |
1554 | 1534 |
1555 // Checks if the type of operand Op is the valid pointer type, for | 1535 // Checks if the type of operand Op is the valid pointer type, for the given |
1556 // the given InstructionName. Returns true if valid. Otherwise | 1536 // InstructionName. Returns true if valid. Otherwise generates an error |
1557 // generates an error message and returns false. | 1537 // message and returns false. |
1558 bool isValidPointerType(Ice::Operand *Op, const char *InstructionName) { | 1538 bool isValidPointerType(Ice::Operand *Op, const char *InstructionName) { |
1559 Ice::Type PtrType = Ice::getPointerType(); | 1539 Ice::Type PtrType = Ice::getPointerType(); |
1560 if (Op->getType() == PtrType) | 1540 if (Op->getType() == PtrType) |
1561 return true; | 1541 return true; |
1562 std::string Buffer; | 1542 std::string Buffer; |
1563 raw_string_ostream StrBuf(Buffer); | 1543 raw_string_ostream StrBuf(Buffer); |
1564 StrBuf << InstructionName << " address not " << PtrType | 1544 StrBuf << InstructionName << " address not " << PtrType |
1565 << ". Found: " << *Op; | 1545 << ". Found: " << *Op; |
1566 Error(StrBuf.str()); | 1546 Error(StrBuf.str()); |
1567 return false; | 1547 return false; |
1568 } | 1548 } |
1569 | 1549 |
1570 // Checks if loading/storing a value of type Ty is allowed. | 1550 // Checks if loading/storing a value of type Ty is allowed. Returns true if |
1571 // Returns true if Valid. Otherwise generates an error message and | 1551 // Valid. Otherwise generates an error message and returns false. |
1572 // returns false. | |
1573 bool isValidLoadStoreType(Ice::Type Ty, const char *InstructionName) { | 1552 bool isValidLoadStoreType(Ice::Type Ty, const char *InstructionName) { |
1574 if (isLoadStoreType(Ty)) | 1553 if (isLoadStoreType(Ty)) |
1575 return true; | 1554 return true; |
1576 std::string Buffer; | 1555 std::string Buffer; |
1577 raw_string_ostream StrBuf(Buffer); | 1556 raw_string_ostream StrBuf(Buffer); |
1578 StrBuf << InstructionName << " type not allowed: " << Ty << "*"; | 1557 StrBuf << InstructionName << " type not allowed: " << Ty << "*"; |
1579 Error(StrBuf.str()); | 1558 Error(StrBuf.str()); |
1580 return false; | 1559 return false; |
1581 } | 1560 } |
1582 | 1561 |
1583 // Checks if loading/storing a value of type Ty is allowed for | 1562 // Checks if loading/storing a value of type Ty is allowed for the given |
1584 // the given Alignment. Otherwise generates an error message and | 1563 // Alignment. Otherwise generates an error message and returns false. |
1585 // returns false. | |
1586 bool isValidLoadStoreAlignment(size_t Alignment, Ice::Type Ty, | 1564 bool isValidLoadStoreAlignment(size_t Alignment, Ice::Type Ty, |
1587 const char *InstructionName) { | 1565 const char *InstructionName) { |
1588 if (!isValidLoadStoreType(Ty, InstructionName)) | 1566 if (!isValidLoadStoreType(Ty, InstructionName)) |
1589 return false; | 1567 return false; |
1590 if (isAllowedAlignment(Alignment, Ty)) | 1568 if (isAllowedAlignment(Alignment, Ty)) |
1591 return true; | 1569 return true; |
1592 std::string Buffer; | 1570 std::string Buffer; |
1593 raw_string_ostream StrBuf(Buffer); | 1571 raw_string_ostream StrBuf(Buffer); |
1594 StrBuf << InstructionName << " " << Ty << "*: not allowed for alignment " | 1572 StrBuf << InstructionName << " " << Ty << "*: not allowed for alignment " |
1595 << Alignment; | 1573 << Alignment; |
1596 Error(StrBuf.str()); | 1574 Error(StrBuf.str()); |
1597 return false; | 1575 return false; |
1598 } | 1576 } |
1599 | 1577 |
1600 // Defines if the given alignment is valid for the given type. Simplified | 1578 // Defines if the given alignment is valid for the given type. Simplified |
1601 // version of PNaClABIProps::isAllowedAlignment, based on API's offered | 1579 // version of PNaClABIProps::isAllowedAlignment, based on API's offered for |
1602 // for Ice::Type. | 1580 // Ice::Type. |
1603 bool isAllowedAlignment(size_t Alignment, Ice::Type Ty) const { | 1581 bool isAllowedAlignment(size_t Alignment, Ice::Type Ty) const { |
1604 return Alignment == typeAlignInBytes(Ty) || | 1582 return Alignment == typeAlignInBytes(Ty) || |
1605 (Alignment == 1 && !isVectorType(Ty)); | 1583 (Alignment == 1 && !isVectorType(Ty)); |
1606 } | 1584 } |
1607 | 1585 |
1608 // Types of errors that can occur for insertelement and extractelement | 1586 // Types of errors that can occur for insertelement and extractelement |
1609 // instructions. | 1587 // instructions. |
1610 enum VectorIndexCheckValue { | 1588 enum VectorIndexCheckValue { |
1611 VectorIndexNotVector, | 1589 VectorIndexNotVector, |
1612 VectorIndexNotConstant, | 1590 VectorIndexNotConstant, |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1648 const auto *C = dyn_cast<Ice::ConstantInteger32>(Index); | 1626 const auto *C = dyn_cast<Ice::ConstantInteger32>(Index); |
1649 if (C == nullptr) | 1627 if (C == nullptr) |
1650 return VectorIndexNotConstant; | 1628 return VectorIndexNotConstant; |
1651 if (static_cast<size_t>(C->getValue()) >= typeNumElements(VecType)) | 1629 if (static_cast<size_t>(C->getValue()) >= typeNumElements(VecType)) |
1652 return VectorIndexNotInRange; | 1630 return VectorIndexNotInRange; |
1653 if (Index->getType() != Ice::IceType_i32) | 1631 if (Index->getType() != Ice::IceType_i32) |
1654 return VectorIndexNotI32; | 1632 return VectorIndexNotI32; |
1655 return VectorIndexValid; | 1633 return VectorIndexValid; |
1656 } | 1634 } |
1657 | 1635 |
1658 // Takes the PNaCl bitcode binary operator Opcode, and the opcode | 1636 // Takes the PNaCl bitcode binary operator Opcode, and the opcode type Ty, |
1659 // type Ty, and sets Op to the corresponding ICE binary | 1637 // and sets Op to the corresponding ICE binary opcode. Returns true if able |
1660 // opcode. Returns true if able to convert, false otherwise. | 1638 // to convert, false otherwise. |
1661 bool convertBinopOpcode(unsigned Opcode, Ice::Type Ty, | 1639 bool convertBinopOpcode(unsigned Opcode, Ice::Type Ty, |
1662 Ice::InstArithmetic::OpKind &Op) { | 1640 Ice::InstArithmetic::OpKind &Op) { |
1663 switch (Opcode) { | 1641 switch (Opcode) { |
1664 default: { | 1642 default: { |
1665 std::string Buffer; | 1643 std::string Buffer; |
1666 raw_string_ostream StrBuf(Buffer); | 1644 raw_string_ostream StrBuf(Buffer); |
1667 StrBuf << "Binary opcode " << Opcode << "not understood for type " << Ty; | 1645 StrBuf << "Binary opcode " << Opcode << "not understood for type " << Ty; |
1668 Error(StrBuf.str()); | 1646 Error(StrBuf.str()); |
1669 Op = Ice::InstArithmetic::Add; | 1647 Op = Ice::InstArithmetic::Add; |
1670 return false; | 1648 return false; |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1729 return isValidIntegerLogicalOp(Op, Ty); | 1707 return isValidIntegerLogicalOp(Op, Ty); |
1730 case naclbitc::BINOP_OR: | 1708 case naclbitc::BINOP_OR: |
1731 Op = Ice::InstArithmetic::Or; | 1709 Op = Ice::InstArithmetic::Or; |
1732 return isValidIntegerLogicalOp(Op, Ty); | 1710 return isValidIntegerLogicalOp(Op, Ty); |
1733 case naclbitc::BINOP_XOR: | 1711 case naclbitc::BINOP_XOR: |
1734 Op = Ice::InstArithmetic::Xor; | 1712 Op = Ice::InstArithmetic::Xor; |
1735 return isValidIntegerLogicalOp(Op, Ty); | 1713 return isValidIntegerLogicalOp(Op, Ty); |
1736 } | 1714 } |
1737 } | 1715 } |
1738 | 1716 |
1739 /// Simplifies out vector types from Type1 and Type2, if both are vectors | 1717 /// Simplifies out vector types from Type1 and Type2, if both are vectors of |
1740 /// of the same size. Returns true iff both are vectors of the same size, | 1718 /// the same size. Returns true iff both are vectors of the same size, or are |
1741 /// or are both scalar types. | 1719 /// both scalar types. |
1742 static bool simplifyOutCommonVectorType(Ice::Type &Type1, Ice::Type &Type2) { | 1720 static bool simplifyOutCommonVectorType(Ice::Type &Type1, Ice::Type &Type2) { |
1743 bool IsType1Vector = isVectorType(Type1); | 1721 bool IsType1Vector = isVectorType(Type1); |
1744 bool IsType2Vector = isVectorType(Type2); | 1722 bool IsType2Vector = isVectorType(Type2); |
1745 if (IsType1Vector != IsType2Vector) | 1723 if (IsType1Vector != IsType2Vector) |
1746 return false; | 1724 return false; |
1747 if (!IsType1Vector) | 1725 if (!IsType1Vector) |
1748 return true; | 1726 return true; |
1749 if (typeNumElements(Type1) != typeNumElements(Type2)) | 1727 if (typeNumElements(Type1) != typeNumElements(Type2)) |
1750 return false; | 1728 return false; |
1751 Type1 = typeElementType(Type1); | 1729 Type1 = typeElementType(Type1); |
(...skipping 22 matching lines...) Expand all Loading... |
1774 static bool isIntExtCastValid(Ice::Type SourceType, Ice::Type TargetType) { | 1752 static bool isIntExtCastValid(Ice::Type SourceType, Ice::Type TargetType) { |
1775 return isIntTruncCastValid(TargetType, SourceType); | 1753 return isIntTruncCastValid(TargetType, SourceType); |
1776 } | 1754 } |
1777 | 1755 |
1778 /// Returns true iff a floating type extension from SourceType to TargetType | 1756 /// Returns true iff a floating type extension from SourceType to TargetType |
1779 /// is valid. | 1757 /// is valid. |
1780 static bool isFloatExtCastValid(Ice::Type SourceType, Ice::Type TargetType) { | 1758 static bool isFloatExtCastValid(Ice::Type SourceType, Ice::Type TargetType) { |
1781 return isFloatTruncCastValid(TargetType, SourceType); | 1759 return isFloatTruncCastValid(TargetType, SourceType); |
1782 } | 1760 } |
1783 | 1761 |
1784 /// Returns true iff a cast from floating type SourceType to integer | 1762 /// Returns true iff a cast from floating type SourceType to integer type |
1785 /// type TargetType is valid. | 1763 /// TargetType is valid. |
1786 static bool isFloatToIntCastValid(Ice::Type SourceType, | 1764 static bool isFloatToIntCastValid(Ice::Type SourceType, |
1787 Ice::Type TargetType) { | 1765 Ice::Type TargetType) { |
1788 if (!(Ice::isFloatingType(SourceType) && Ice::isIntegerType(TargetType))) | 1766 if (!(Ice::isFloatingType(SourceType) && Ice::isIntegerType(TargetType))) |
1789 return false; | 1767 return false; |
1790 bool IsSourceVector = isVectorType(SourceType); | 1768 bool IsSourceVector = isVectorType(SourceType); |
1791 bool IsTargetVector = isVectorType(TargetType); | 1769 bool IsTargetVector = isVectorType(TargetType); |
1792 if (IsSourceVector != IsTargetVector) | 1770 if (IsSourceVector != IsTargetVector) |
1793 return false; | 1771 return false; |
1794 if (IsSourceVector) { | 1772 if (IsSourceVector) { |
1795 return typeNumElements(SourceType) == typeNumElements(TargetType); | 1773 return typeNumElements(SourceType) == typeNumElements(TargetType); |
1796 } | 1774 } |
1797 return true; | 1775 return true; |
1798 } | 1776 } |
1799 | 1777 |
1800 /// Returns true iff a cast from integer type SourceType to floating | 1778 /// Returns true iff a cast from integer type SourceType to floating type |
1801 /// type TargetType is valid. | 1779 /// TargetType is valid. |
1802 static bool isIntToFloatCastValid(Ice::Type SourceType, | 1780 static bool isIntToFloatCastValid(Ice::Type SourceType, |
1803 Ice::Type TargetType) { | 1781 Ice::Type TargetType) { |
1804 return isFloatToIntCastValid(TargetType, SourceType); | 1782 return isFloatToIntCastValid(TargetType, SourceType); |
1805 } | 1783 } |
1806 | 1784 |
1807 /// Returns the number of bits used to model type Ty when defining the | 1785 /// Returns the number of bits used to model type Ty when defining the bitcast |
1808 /// bitcast instruction. | 1786 /// instruction. |
1809 static Ice::SizeT bitcastSizeInBits(Ice::Type Ty) { | 1787 static Ice::SizeT bitcastSizeInBits(Ice::Type Ty) { |
1810 if (Ice::isVectorType(Ty)) | 1788 if (Ice::isVectorType(Ty)) |
1811 return Ice::typeNumElements(Ty) * | 1789 return Ice::typeNumElements(Ty) * |
1812 bitcastSizeInBits(Ice::typeElementType(Ty)); | 1790 bitcastSizeInBits(Ice::typeElementType(Ty)); |
1813 if (Ty == Ice::IceType_i1) | 1791 if (Ty == Ice::IceType_i1) |
1814 return 1; | 1792 return 1; |
1815 return Ice::typeWidthInBytes(Ty) * CHAR_BIT; | 1793 return Ice::typeWidthInBytes(Ty) * CHAR_BIT; |
1816 } | 1794 } |
1817 | 1795 |
1818 /// Returns true iff a bitcast from SourceType to TargetType is allowed. | 1796 /// Returns true iff a bitcast from SourceType to TargetType is allowed. |
1819 static bool isBitcastValid(Ice::Type SourceType, Ice::Type TargetType) { | 1797 static bool isBitcastValid(Ice::Type SourceType, Ice::Type TargetType) { |
1820 return bitcastSizeInBits(SourceType) == bitcastSizeInBits(TargetType); | 1798 return bitcastSizeInBits(SourceType) == bitcastSizeInBits(TargetType); |
1821 } | 1799 } |
1822 | 1800 |
1823 /// Returns true iff the NaCl bitcode Opcode is a valid cast opcode | 1801 /// Returns true iff the NaCl bitcode Opcode is a valid cast opcode for |
1824 /// for converting SourceType to TargetType. Updates CastKind to the | 1802 /// converting SourceType to TargetType. Updates CastKind to the corresponding |
1825 /// corresponding instruction cast opcode. Also generates an error | 1803 /// instruction cast opcode. Also generates an error message when this |
1826 /// message when this function returns false. | 1804 /// function returns false. |
1827 bool convertCastOpToIceOp(uint64_t Opcode, Ice::Type SourceType, | 1805 bool convertCastOpToIceOp(uint64_t Opcode, Ice::Type SourceType, |
1828 Ice::Type TargetType, | 1806 Ice::Type TargetType, |
1829 Ice::InstCast::OpKind &CastKind) { | 1807 Ice::InstCast::OpKind &CastKind) { |
1830 bool Result; | 1808 bool Result; |
1831 switch (Opcode) { | 1809 switch (Opcode) { |
1832 default: { | 1810 default: { |
1833 std::string Buffer; | 1811 std::string Buffer; |
1834 raw_string_ostream StrBuf(Buffer); | 1812 raw_string_ostream StrBuf(Buffer); |
1835 StrBuf << "Cast opcode " << Opcode << " not understood.\n"; | 1813 StrBuf << "Cast opcode " << Opcode << " not understood.\n"; |
1836 Error(StrBuf.str()); | 1814 Error(StrBuf.str()); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1881 if (!Result) { | 1859 if (!Result) { |
1882 std::string Buffer; | 1860 std::string Buffer; |
1883 raw_string_ostream StrBuf(Buffer); | 1861 raw_string_ostream StrBuf(Buffer); |
1884 StrBuf << "Illegal cast: " << Ice::InstCast::getCastName(CastKind) << " " | 1862 StrBuf << "Illegal cast: " << Ice::InstCast::getCastName(CastKind) << " " |
1885 << SourceType << " to " << TargetType; | 1863 << SourceType << " to " << TargetType; |
1886 Error(StrBuf.str()); | 1864 Error(StrBuf.str()); |
1887 } | 1865 } |
1888 return Result; | 1866 return Result; |
1889 } | 1867 } |
1890 | 1868 |
1891 // Converts PNaCl bitcode Icmp operator to corresponding ICE op. | 1869 // Converts PNaCl bitcode Icmp operator to corresponding ICE op. Returns true |
1892 // Returns true if able to convert, false otherwise. | 1870 // if able to convert, false otherwise. |
1893 bool convertNaClBitcICmpOpToIce(uint64_t Op, | 1871 bool convertNaClBitcICmpOpToIce(uint64_t Op, |
1894 Ice::InstIcmp::ICond &Cond) const { | 1872 Ice::InstIcmp::ICond &Cond) const { |
1895 switch (Op) { | 1873 switch (Op) { |
1896 case naclbitc::ICMP_EQ: | 1874 case naclbitc::ICMP_EQ: |
1897 Cond = Ice::InstIcmp::Eq; | 1875 Cond = Ice::InstIcmp::Eq; |
1898 return true; | 1876 return true; |
1899 case naclbitc::ICMP_NE: | 1877 case naclbitc::ICMP_NE: |
1900 Cond = Ice::InstIcmp::Ne; | 1878 Cond = Ice::InstIcmp::Ne; |
1901 return true; | 1879 return true; |
1902 case naclbitc::ICMP_UGT: | 1880 case naclbitc::ICMP_UGT: |
(...skipping 20 matching lines...) Expand all Loading... |
1923 case naclbitc::ICMP_SLE: | 1901 case naclbitc::ICMP_SLE: |
1924 Cond = Ice::InstIcmp::Sle; | 1902 Cond = Ice::InstIcmp::Sle; |
1925 return true; | 1903 return true; |
1926 default: | 1904 default: |
1927 // Make sure Cond is always initialized. | 1905 // Make sure Cond is always initialized. |
1928 Cond = static_cast<Ice::InstIcmp::ICond>(0); | 1906 Cond = static_cast<Ice::InstIcmp::ICond>(0); |
1929 return false; | 1907 return false; |
1930 } | 1908 } |
1931 } | 1909 } |
1932 | 1910 |
1933 // Converts PNaCl bitcode Fcmp operator to corresponding ICE op. | 1911 // Converts PNaCl bitcode Fcmp operator to corresponding ICE op. Returns true |
1934 // Returns true if able to convert, false otherwise. | 1912 // if able to convert, false otherwise. |
1935 bool convertNaClBitcFCompOpToIce(uint64_t Op, | 1913 bool convertNaClBitcFCompOpToIce(uint64_t Op, |
1936 Ice::InstFcmp::FCond &Cond) const { | 1914 Ice::InstFcmp::FCond &Cond) const { |
1937 switch (Op) { | 1915 switch (Op) { |
1938 case naclbitc::FCMP_FALSE: | 1916 case naclbitc::FCMP_FALSE: |
1939 Cond = Ice::InstFcmp::False; | 1917 Cond = Ice::InstFcmp::False; |
1940 return true; | 1918 return true; |
1941 case naclbitc::FCMP_OEQ: | 1919 case naclbitc::FCMP_OEQ: |
1942 Cond = Ice::InstFcmp::Oeq; | 1920 Cond = Ice::InstFcmp::Oeq; |
1943 return true; | 1921 return true; |
1944 case naclbitc::FCMP_OGT: | 1922 case naclbitc::FCMP_OGT: |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1983 case naclbitc::FCMP_TRUE: | 1961 case naclbitc::FCMP_TRUE: |
1984 Cond = Ice::InstFcmp::True; | 1962 Cond = Ice::InstFcmp::True; |
1985 return true; | 1963 return true; |
1986 default: | 1964 default: |
1987 // Make sure Cond is always initialized. | 1965 // Make sure Cond is always initialized. |
1988 Cond = static_cast<Ice::InstFcmp::FCond>(0); | 1966 Cond = static_cast<Ice::InstFcmp::FCond>(0); |
1989 return false; | 1967 return false; |
1990 } | 1968 } |
1991 } | 1969 } |
1992 | 1970 |
1993 // Creates an error instruction, generating a value of type Ty, and | 1971 // Creates an error instruction, generating a value of type Ty, and adds a |
1994 // adds a placeholder so that instruction indices line up. | 1972 // placeholder so that instruction indices line up. Some instructions, such |
1995 // Some instructions, such as a call, will not generate a value | 1973 // as a call, will not generate a value if the return type is void. In such |
1996 // if the return type is void. In such cases, a placeholder value | 1974 // cases, a placeholder value for the badly formed instruction is not needed. |
1997 // for the badly formed instruction is not needed. Hence, if Ty is | 1975 // Hence, if Ty is void, an error instruction is not appended. |
1998 // void, an error instruction is not appended. | |
1999 void appendErrorInstruction(Ice::Type Ty) { | 1976 void appendErrorInstruction(Ice::Type Ty) { |
2000 // Note: we don't worry about downstream translation errors because | 1977 // Note: we don't worry about downstream translation errors because the |
2001 // the function will not be translated if any errors occur. | 1978 // function will not be translated if any errors occur. |
2002 if (Ty == Ice::IceType_void) | 1979 if (Ty == Ice::IceType_void) |
2003 return; | 1980 return; |
2004 Ice::Variable *Var = getNextInstVar(Ty); | 1981 Ice::Variable *Var = getNextInstVar(Ty); |
2005 CurrentNode->appendInst(Ice::InstAssign::create(Func.get(), Var, Var)); | 1982 CurrentNode->appendInst(Ice::InstAssign::create(Func.get(), Var, Var)); |
2006 } | 1983 } |
2007 }; | 1984 }; |
2008 | 1985 |
2009 void FunctionParser::ExitBlock() { | 1986 void FunctionParser::ExitBlock() { |
2010 // Check if the last instruction in the function was terminating. | 1987 // Check if the last instruction in the function was terminating. |
2011 if (!InstIsTerminating) { | 1988 if (!InstIsTerminating) { |
2012 Error("Last instruction in function not terminator"); | 1989 Error("Last instruction in function not terminator"); |
2013 if (isIRGenerationDisabled()) | 1990 if (isIRGenerationDisabled()) |
2014 return; | 1991 return; |
2015 // Recover by inserting an unreachable instruction. | 1992 // Recover by inserting an unreachable instruction. |
2016 CurrentNode->appendInst(Ice::InstUnreachable::create(Func.get())); | 1993 CurrentNode->appendInst(Ice::InstUnreachable::create(Func.get())); |
2017 } | 1994 } |
2018 ++CurrentBbIndex; | 1995 ++CurrentBbIndex; |
2019 if (CurrentBbIndex != DeclaredNumberBbs) { | 1996 if (CurrentBbIndex != DeclaredNumberBbs) { |
2020 std::string Buffer; | 1997 std::string Buffer; |
2021 raw_string_ostream StrBuf(Buffer); | 1998 raw_string_ostream StrBuf(Buffer); |
2022 StrBuf << "Function declared " << DeclaredNumberBbs | 1999 StrBuf << "Function declared " << DeclaredNumberBbs |
2023 << " basic blocks, but defined " << CurrentBbIndex << "."; | 2000 << " basic blocks, but defined " << CurrentBbIndex << "."; |
2024 Error(StrBuf.str()); | 2001 Error(StrBuf.str()); |
2025 } | 2002 } |
2026 if (isIRGenerationDisabled()) | 2003 if (isIRGenerationDisabled()) |
2027 return; | 2004 return; |
2028 // Before translating, check for blocks without instructions, and | 2005 // Before translating, check for blocks without instructions, and insert |
2029 // insert unreachable. This shouldn't happen, but be safe. | 2006 // unreachable. This shouldn't happen, but be safe. |
2030 size_t Index = 0; | 2007 size_t Index = 0; |
2031 for (Ice::CfgNode *Node : Func->getNodes()) { | 2008 for (Ice::CfgNode *Node : Func->getNodes()) { |
2032 if (Node->getInsts().empty()) { | 2009 if (Node->getInsts().empty()) { |
2033 std::string Buffer; | 2010 std::string Buffer; |
2034 raw_string_ostream StrBuf(Buffer); | 2011 raw_string_ostream StrBuf(Buffer); |
2035 StrBuf << "Basic block " << Index << " contains no instructions"; | 2012 StrBuf << "Basic block " << Index << " contains no instructions"; |
2036 Error(StrBuf.str()); | 2013 Error(StrBuf.str()); |
2037 Node->appendInst(Ice::InstUnreachable::create(Func.get())); | 2014 Node->appendInst(Ice::InstUnreachable::create(Func.get())); |
2038 } | 2015 } |
2039 ++Index; | 2016 ++Index; |
2040 } | 2017 } |
2041 Func->computeInOutEdges(); | 2018 Func->computeInOutEdges(); |
2042 } | 2019 } |
2043 | 2020 |
2044 void FunctionParser::reportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op, | 2021 void FunctionParser::reportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op, |
2045 Ice::Type OpTy) { | 2022 Ice::Type OpTy) { |
2046 std::string Buffer; | 2023 std::string Buffer; |
2047 raw_string_ostream StrBuf(Buffer); | 2024 raw_string_ostream StrBuf(Buffer); |
2048 StrBuf << "Invalid operator type for " << Ice::InstArithmetic::getOpName(Op) | 2025 StrBuf << "Invalid operator type for " << Ice::InstArithmetic::getOpName(Op) |
2049 << ". Found " << OpTy; | 2026 << ". Found " << OpTy; |
2050 Error(StrBuf.str()); | 2027 Error(StrBuf.str()); |
2051 } | 2028 } |
2052 | 2029 |
2053 void FunctionParser::ProcessRecord() { | 2030 void FunctionParser::ProcessRecord() { |
2054 // Note: To better separate parse/IR generation times, when IR generation | 2031 // Note: To better separate parse/IR generation times, when IR generation is |
2055 // is disabled we do the following: | 2032 // disabled we do the following: |
2056 // 1) Delay exiting until after we extract operands. | 2033 // 1) Delay exiting until after we extract operands. |
2057 // 2) return before we access operands, since all operands will be a nullptr. | 2034 // 2) return before we access operands, since all operands will be a nullptr. |
2058 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); | 2035 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); |
2059 if (InstIsTerminating) { | 2036 if (InstIsTerminating) { |
2060 InstIsTerminating = false; | 2037 InstIsTerminating = false; |
2061 ++CurrentBbIndex; | 2038 ++CurrentBbIndex; |
2062 if (!isIRGenerationDisabled()) | 2039 if (!isIRGenerationDisabled()) |
2063 CurrentNode = getBasicBlock(CurrentBbIndex); | 2040 CurrentNode = getBasicBlock(CurrentBbIndex); |
2064 } | 2041 } |
2065 // The base index for relative indexing. | 2042 // The base index for relative indexing. |
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2375 return; | 2352 return; |
2376 CurrentNode->appendInst( | 2353 CurrentNode->appendInst( |
2377 Ice::InstBr::create(Func.get(), Cond, ThenBlock, ElseBlock)); | 2354 Ice::InstBr::create(Func.get(), Cond, ThenBlock, ElseBlock)); |
2378 } | 2355 } |
2379 return; | 2356 return; |
2380 } | 2357 } |
2381 case naclbitc::FUNC_CODE_INST_SWITCH: { | 2358 case naclbitc::FUNC_CODE_INST_SWITCH: { |
2382 // SWITCH: [Condty, Cond, BbIndex, NumCases Case ...] | 2359 // SWITCH: [Condty, Cond, BbIndex, NumCases Case ...] |
2383 // where Case = [1, 1, Value, BbIndex]. | 2360 // where Case = [1, 1, Value, BbIndex]. |
2384 // | 2361 // |
2385 // Note: Unlike most instructions, we don't infer the type of | 2362 // Note: Unlike most instructions, we don't infer the type of Cond, but |
2386 // Cond, but provide it as a separate field. There are also | 2363 // provide it as a separate field. There are also unnecessary data fields |
2387 // unnecesary data fields (i.e. constants 1). These were not | 2364 // (i.e. constants 1). These were not cleaned up in PNaCl bitcode because |
2388 // cleaned up in PNaCl bitcode because the bitcode format was | 2365 // the bitcode format was already frozen when the problem was noticed. |
2389 // already frozen when the problem was noticed. | |
2390 InstIsTerminating = true; | 2366 InstIsTerminating = true; |
2391 if (!isValidRecordSizeAtLeast(4, "switch")) | 2367 if (!isValidRecordSizeAtLeast(4, "switch")) |
2392 return; | 2368 return; |
2393 | 2369 |
2394 Ice::Type CondTy = Context->getSimpleTypeByID(Values[0]); | 2370 Ice::Type CondTy = Context->getSimpleTypeByID(Values[0]); |
2395 if (!Ice::isScalarIntegerType(CondTy)) { | 2371 if (!Ice::isScalarIntegerType(CondTy)) { |
2396 std::string Buffer; | 2372 std::string Buffer; |
2397 raw_string_ostream StrBuf(Buffer); | 2373 raw_string_ostream StrBuf(Buffer); |
2398 StrBuf << "Case condition must be non-wide integer. Found: " << CondTy; | 2374 StrBuf << "Case condition must be non-wide integer. Found: " << CondTy; |
2399 Error(StrBuf.str()); | 2375 Error(StrBuf.str()); |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2584 return; | 2560 return; |
2585 CurrentNode->appendInst( | 2561 CurrentNode->appendInst( |
2586 Ice::InstStore::create(Func.get(), Value, Address, Alignment)); | 2562 Ice::InstStore::create(Func.get(), Value, Address, Alignment)); |
2587 return; | 2563 return; |
2588 } | 2564 } |
2589 case naclbitc::FUNC_CODE_INST_CALL: | 2565 case naclbitc::FUNC_CODE_INST_CALL: |
2590 case naclbitc::FUNC_CODE_INST_CALL_INDIRECT: { | 2566 case naclbitc::FUNC_CODE_INST_CALL_INDIRECT: { |
2591 // CALL: [cc, fnid, arg0, arg1...] | 2567 // CALL: [cc, fnid, arg0, arg1...] |
2592 // CALL_INDIRECT: [cc, fn, returnty, args...] | 2568 // CALL_INDIRECT: [cc, fn, returnty, args...] |
2593 // | 2569 // |
2594 // Note: The difference between CALL and CALL_INDIRECT is that | 2570 // Note: The difference between CALL and CALL_INDIRECT is that CALL has a |
2595 // CALL has a reference to an explicit function declaration, while | 2571 // reference to an explicit function declaration, while the CALL_INDIRECT |
2596 // the CALL_INDIRECT is just an address. For CALL, we can infer | 2572 // is just an address. For CALL, we can infer the return type by looking up |
2597 // the return type by looking up the type signature associated | 2573 // the type signature associated with the function declaration. For |
2598 // with the function declaration. For CALL_INDIRECT we can only | 2574 // CALL_INDIRECT we can only infer the type signature via argument types, |
2599 // infer the type signature via argument types, and the | 2575 // and the corresponding return type stored in CALL_INDIRECT record. |
2600 // corresponding return type stored in CALL_INDIRECT record. | |
2601 Ice::SizeT ParamsStartIndex = 2; | 2576 Ice::SizeT ParamsStartIndex = 2; |
2602 if (Record.GetCode() == naclbitc::FUNC_CODE_INST_CALL) { | 2577 if (Record.GetCode() == naclbitc::FUNC_CODE_INST_CALL) { |
2603 if (!isValidRecordSizeAtLeast(2, "call")) | 2578 if (!isValidRecordSizeAtLeast(2, "call")) |
2604 return; | 2579 return; |
2605 } else { | 2580 } else { |
2606 if (!isValidRecordSizeAtLeast(3, "call indirect")) | 2581 if (!isValidRecordSizeAtLeast(3, "call indirect")) |
2607 return; | 2582 return; |
2608 ParamsStartIndex = 3; | 2583 ParamsStartIndex = 3; |
2609 } | 2584 } |
2610 | 2585 |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2756 Ice::TimerMarker Timer; | 2731 Ice::TimerMarker Timer; |
2757 // The parser of the function block this constants block appears in. | 2732 // The parser of the function block this constants block appears in. |
2758 FunctionParser *FuncParser; | 2733 FunctionParser *FuncParser; |
2759 // The type to use for succeeding constants. | 2734 // The type to use for succeeding constants. |
2760 Ice::Type NextConstantType = Ice::IceType_void; | 2735 Ice::Type NextConstantType = Ice::IceType_void; |
2761 | 2736 |
2762 void ProcessRecord() override; | 2737 void ProcessRecord() override; |
2763 | 2738 |
2764 Ice::GlobalContext *getContext() { return getTranslator().getContext(); } | 2739 Ice::GlobalContext *getContext() { return getTranslator().getContext(); } |
2765 | 2740 |
2766 // Returns true if the type to use for succeeding constants is defined. | 2741 // Returns true if the type to use for succeeding constants is defined. If |
2767 // If false, also generates an error message. | 2742 // false, also generates an error message. |
2768 bool isValidNextConstantType() { | 2743 bool isValidNextConstantType() { |
2769 if (NextConstantType != Ice::IceType_void) | 2744 if (NextConstantType != Ice::IceType_void) |
2770 return true; | 2745 return true; |
2771 Error("Constant record not preceded by set type record"); | 2746 Error("Constant record not preceded by set type record"); |
2772 return false; | 2747 return false; |
2773 } | 2748 } |
2774 }; | 2749 }; |
2775 | 2750 |
2776 void ConstantsParser::ProcessRecord() { | 2751 void ConstantsParser::ProcessRecord() { |
2777 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); | 2752 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2880 private: | 2855 private: |
2881 Ice::TimerMarker Timer; | 2856 Ice::TimerMarker Timer; |
2882 // Returns the enclosing function parser. | 2857 // Returns the enclosing function parser. |
2883 FunctionParser *getFunctionParser() const { | 2858 FunctionParser *getFunctionParser() const { |
2884 return reinterpret_cast<FunctionParser *>(GetEnclosingParser()); | 2859 return reinterpret_cast<FunctionParser *>(GetEnclosingParser()); |
2885 } | 2860 } |
2886 | 2861 |
2887 void setValueName(NaClBcIndexSize_t Index, StringType &Name) override; | 2862 void setValueName(NaClBcIndexSize_t Index, StringType &Name) override; |
2888 void setBbName(NaClBcIndexSize_t Index, StringType &Name) override; | 2863 void setBbName(NaClBcIndexSize_t Index, StringType &Name) override; |
2889 | 2864 |
2890 // Reports that the assignment of Name to the value associated with | 2865 // Reports that the assignment of Name to the value associated with index is |
2891 // index is not possible, for the given Context. | 2866 // not possible, for the given Context. |
2892 void reportUnableToAssign(const char *Context, NaClBcIndexSize_t Index, | 2867 void reportUnableToAssign(const char *Context, NaClBcIndexSize_t Index, |
2893 StringType &Name) { | 2868 StringType &Name) { |
2894 std::string Buffer; | 2869 std::string Buffer; |
2895 raw_string_ostream StrBuf(Buffer); | 2870 raw_string_ostream StrBuf(Buffer); |
2896 StrBuf << "Function-local " << Context << " name '" << Name | 2871 StrBuf << "Function-local " << Context << " name '" << Name |
2897 << "' can't be associated with index " << Index; | 2872 << "' can't be associated with index " << Index; |
2898 Error(StrBuf.str()); | 2873 Error(StrBuf.str()); |
2899 } | 2874 } |
2900 }; | 2875 }; |
2901 | 2876 |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2969 ~ModuleParser() override = default; | 2944 ~ModuleParser() override = default; |
2970 | 2945 |
2971 const char *getBlockName() const override { return "module"; } | 2946 const char *getBlockName() const override { return "module"; } |
2972 | 2947 |
2973 private: | 2948 private: |
2974 Ice::TimerMarker Timer; | 2949 Ice::TimerMarker Timer; |
2975 // True if we have already installed names for unnamed global declarations, | 2950 // True if we have already installed names for unnamed global declarations, |
2976 // and have generated global constant initializers. | 2951 // and have generated global constant initializers. |
2977 bool GlobalDeclarationNamesAndInitializersInstalled = false; | 2952 bool GlobalDeclarationNamesAndInitializersInstalled = false; |
2978 | 2953 |
2979 // Generates names for unnamed global addresses (i.e. functions and | 2954 // Generates names for unnamed global addresses (i.e. functions and global |
2980 // global variables). Then lowers global variable declaration | 2955 // variables). Then lowers global variable declaration initializers to the |
2981 // initializers to the target. May be called multiple times. Only | 2956 // target. May be called multiple times. Only the first call will do the |
2982 // the first call will do the installation. | 2957 // installation. |
2983 void installGlobalNamesAndGlobalVarInitializers() { | 2958 void installGlobalNamesAndGlobalVarInitializers() { |
2984 if (!GlobalDeclarationNamesAndInitializersInstalled) { | 2959 if (!GlobalDeclarationNamesAndInitializersInstalled) { |
2985 Context->installGlobalNames(); | 2960 Context->installGlobalNames(); |
2986 Context->createValueIDs(); | 2961 Context->createValueIDs(); |
2987 getTranslator().lowerGlobals(Context->getGlobalVariables()); | 2962 getTranslator().lowerGlobals(Context->getGlobalVariables()); |
2988 GlobalDeclarationNamesAndInitializersInstalled = true; | 2963 GlobalDeclarationNamesAndInitializersInstalled = true; |
2989 } | 2964 } |
2990 } | 2965 } |
2991 bool ParseBlock(unsigned BlockID) override; | 2966 bool ParseBlock(unsigned BlockID) override; |
2992 | 2967 |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3123 void PNaClTranslator::translateBuffer(const std::string &IRFilename, | 3098 void PNaClTranslator::translateBuffer(const std::string &IRFilename, |
3124 MemoryBuffer *MemBuf) { | 3099 MemoryBuffer *MemBuf) { |
3125 std::unique_ptr<MemoryObject> MemObj(getNonStreamedMemoryObject( | 3100 std::unique_ptr<MemoryObject> MemObj(getNonStreamedMemoryObject( |
3126 reinterpret_cast<const unsigned char *>(MemBuf->getBufferStart()), | 3101 reinterpret_cast<const unsigned char *>(MemBuf->getBufferStart()), |
3127 reinterpret_cast<const unsigned char *>(MemBuf->getBufferEnd()))); | 3102 reinterpret_cast<const unsigned char *>(MemBuf->getBufferEnd()))); |
3128 translate(IRFilename, std::move(MemObj)); | 3103 translate(IRFilename, std::move(MemObj)); |
3129 } | 3104 } |
3130 | 3105 |
3131 void PNaClTranslator::translate(const std::string &IRFilename, | 3106 void PNaClTranslator::translate(const std::string &IRFilename, |
3132 std::unique_ptr<MemoryObject> &&MemObj) { | 3107 std::unique_ptr<MemoryObject> &&MemObj) { |
3133 // On error, we report_fatal_error to avoid destroying the MemObj. | 3108 // On error, we report_fatal_error to avoid destroying the MemObj. That may |
3134 // That may still be in use by IceBrowserCompileServer. Otherwise, | 3109 // still be in use by IceBrowserCompileServer. Otherwise, we need to change |
3135 // we need to change the MemObj to be ref-counted, or have a wrapper, | 3110 // the MemObj to be ref-counted, or have a wrapper, or simply leak. We also |
3136 // or simply leak. We also need a hook to tell the IceBrowserCompileServer | 3111 // need a hook to tell the IceBrowserCompileServer to unblock its |
3137 // to unblock its QueueStreamer. | 3112 // QueueStreamer. |
3138 // https://code.google.com/p/nativeclient/issues/detail?id=4163 | 3113 // https://code.google.com/p/nativeclient/issues/detail?id=4163 |
3139 Ostream &ErrStream = getContext()->getStrError(); | 3114 Ostream &ErrStream = getContext()->getStrError(); |
3140 // Read header and verify it is good. | 3115 // Read header and verify it is good. |
3141 NaClBitcodeHeader Header; | 3116 NaClBitcodeHeader Header; |
3142 if (Header.Read(MemObj.get())) { | 3117 if (Header.Read(MemObj.get())) { |
3143 llvm::report_fatal_error("Invalid PNaCl bitcode header"); | 3118 llvm::report_fatal_error("Invalid PNaCl bitcode header"); |
3144 } | 3119 } |
3145 if (!Header.IsSupported()) { | 3120 if (!Header.IsSupported()) { |
3146 ErrStream << Header.Unsupported(); | 3121 ErrStream << Header.Unsupported(); |
3147 if (!Header.IsReadable()) { | 3122 if (!Header.IsReadable()) { |
(...skipping 23 matching lines...) Expand all Loading... |
3171 } | 3146 } |
3172 if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) { | 3147 if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) { |
3173 ErrStream | 3148 ErrStream |
3174 << IRFilename | 3149 << IRFilename |
3175 << ": Bitcode stream should be a multiple of 4 bytes in length.\n"; | 3150 << ": Bitcode stream should be a multiple of 4 bytes in length.\n"; |
3176 llvm::report_fatal_error("Bitcode stream should be a multiple of 4 bytes"); | 3151 llvm::report_fatal_error("Bitcode stream should be a multiple of 4 bytes"); |
3177 } | 3152 } |
3178 } | 3153 } |
3179 | 3154 |
3180 } // end of namespace Ice | 3155 } // end of namespace Ice |
OLD | NEW |