| OLD | NEW |
| 1 //===- subzero/src/PNaClTranslator.cpp - ICE from bitcode -----------------===// | 1 //===- subzero/src/PNaClTranslator.cpp - ICE from bitcode -----------------===// |
| 2 // | 2 // |
| 3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
| 4 // | 4 // |
| 5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
| 7 // | 7 // |
| 8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
| 9 // | 9 // |
| 10 // This file implements the PNaCl bitcode file to Ice, to machine code | 10 // This file implements the PNaCl bitcode file to Ice, to machine code |
| 11 // translator. | 11 // translator. |
| 12 // | 12 // |
| 13 //===----------------------------------------------------------------------===// | 13 //===----------------------------------------------------------------------===// |
| 14 | 14 |
| 15 #include "llvm/ADT/SmallString.h" | 15 #include "llvm/ADT/SmallString.h" |
| 16 #include "llvm/Bitcode/NaCl/NaClBitcodeDecoders.h" | 16 #include "llvm/Bitcode/NaCl/NaClBitcodeDecoders.h" |
| 17 #include "llvm/Bitcode/NaCl/NaClBitcodeDefs.h" |
| 17 #include "llvm/Bitcode/NaCl/NaClBitcodeHeader.h" | 18 #include "llvm/Bitcode/NaCl/NaClBitcodeHeader.h" |
| 18 #include "llvm/Bitcode/NaCl/NaClBitcodeParser.h" | 19 #include "llvm/Bitcode/NaCl/NaClBitcodeParser.h" |
| 19 #include "llvm/Bitcode/NaCl/NaClReaderWriter.h" | 20 #include "llvm/Bitcode/NaCl/NaClReaderWriter.h" |
| 20 #include "llvm/Support/Format.h" | 21 #include "llvm/Support/Format.h" |
| 21 #include "llvm/Support/MemoryBuffer.h" | 22 #include "llvm/Support/MemoryBuffer.h" |
| 22 #include "llvm/Support/raw_ostream.h" | 23 #include "llvm/Support/raw_ostream.h" |
| 23 | 24 |
| 24 #include "IceAPInt.h" | 25 #include "IceAPInt.h" |
| 25 #include "IceAPFloat.h" | 26 #include "IceAPFloat.h" |
| 26 #include "IceCfg.h" | 27 #include "IceCfg.h" |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 175 void setBlockParser(BlockParserBaseClass *NewBlockParser) { | 176 void setBlockParser(BlockParserBaseClass *NewBlockParser) { |
| 176 BlockParser = NewBlockParser; | 177 BlockParser = NewBlockParser; |
| 177 } | 178 } |
| 178 | 179 |
| 179 /// Generates error with given Message, occurring at BitPosition | 180 /// Generates error with given Message, occurring at BitPosition |
| 180 /// within the bitcode file. Always returns true. | 181 /// within the bitcode file. Always returns true. |
| 181 bool ErrorAt(naclbitc::ErrorLevel Level, uint64_t BitPosition, | 182 bool ErrorAt(naclbitc::ErrorLevel Level, uint64_t BitPosition, |
| 182 const std::string &Message) final; | 183 const std::string &Message) final; |
| 183 | 184 |
| 184 /// Generates error message with respect to the current block parser. | 185 /// Generates error message with respect to the current block parser. |
| 185 bool BlockError(const std::string &Message); | 186 bool blockError(const std::string &Message); |
| 186 | 187 |
| 187 /// Returns the number of errors found while parsing the bitcode | 188 /// Returns the number of errors found while parsing the bitcode |
| 188 /// file. | 189 /// file. |
| 189 unsigned getNumErrors() const { return NumErrors; } | 190 unsigned getNumErrors() const { return NumErrors; } |
| 190 | 191 |
| 191 /// Changes the size of the type list to the given size. | 192 /// Changes the size of the type list to the given size. |
| 192 void resizeTypeIDValues(unsigned NewSize) { TypeIDValues.resize(NewSize); } | 193 void resizeTypeIDValues(size_t NewSize) { TypeIDValues.resize(NewSize); } |
| 194 |
| 195 size_t getNumTypeIDValues() const { return TypeIDValues.size(); } |
| 193 | 196 |
| 194 /// Returns true if generation of Subzero IR is disabled. | 197 /// Returns true if generation of Subzero IR is disabled. |
| 195 bool isIRGenerationDisabled() const { | 198 bool isIRGenerationDisabled() const { |
| 196 return Translator.getFlags().getDisableIRGeneration(); | 199 return Translator.getFlags().getDisableIRGeneration(); |
| 197 } | 200 } |
| 198 | 201 |
| 199 /// Returns the undefined type associated with type ID. | 202 /// Returns the undefined type associated with type ID. |
| 200 /// Note: Returns extended type ready to be defined. | 203 /// Note: Returns extended type ready to be defined. |
| 201 ExtendedType *getTypeByIDForDefining(unsigned ID) { | 204 ExtendedType *getTypeByIDForDefining(NaClBcIndexSize_t ID) { |
| 202 // Get corresponding element, verifying the value is still undefined | 205 // Get corresponding element, verifying the value is still undefined |
| 203 // (and hence allowed to be defined). | 206 // (and hence allowed to be defined). |
| 204 ExtendedType *Ty = getTypeByIDAsKind(ID, ExtendedType::Undefined); | 207 ExtendedType *Ty = getTypeByIDAsKind(ID, ExtendedType::Undefined); |
| 205 if (Ty) | 208 if (Ty) |
| 206 return Ty; | 209 return Ty; |
| 207 if (ID >= TypeIDValues.size()) | 210 if (ID >= TypeIDValues.size()) { |
| 211 if (ID >= NaClBcIndexSize_t_Max) { |
| 212 std::string Buffer; |
| 213 raw_string_ostream StrBuf(Buffer); |
| 214 StrBuf << "Can't define more than " << NaClBcIndexSize_t_Max |
| 215 << " types\n"; |
| 216 blockError(StrBuf.str()); |
| 217 // Recover by using existing type slot. |
| 218 return &TypeIDValues[0]; |
| 219 } |
| 208 TypeIDValues.resize(ID + 1); | 220 TypeIDValues.resize(ID + 1); |
| 221 } |
| 209 return &TypeIDValues[ID]; | 222 return &TypeIDValues[ID]; |
| 210 } | 223 } |
| 211 | 224 |
| 212 /// Returns the type associated with the given index. | 225 /// Returns the type associated with the given index. |
| 213 Ice::Type getSimpleTypeByID(unsigned ID) { | 226 Ice::Type getSimpleTypeByID(NaClBcIndexSize_t ID) { |
| 214 const ExtendedType *Ty = getTypeByIDAsKind(ID, ExtendedType::Simple); | 227 const ExtendedType *Ty = getTypeByIDAsKind(ID, ExtendedType::Simple); |
| 215 if (Ty == nullptr) | 228 if (Ty == nullptr) |
| 216 // Return error recovery value. | 229 // Return error recovery value. |
| 217 return Ice::IceType_void; | 230 return Ice::IceType_void; |
| 218 return cast<SimpleExtendedType>(Ty)->getType(); | 231 return cast<SimpleExtendedType>(Ty)->getType(); |
| 219 } | 232 } |
| 220 | 233 |
| 221 /// Returns the type signature associated with the given index. | 234 /// Returns the type signature associated with the given index. |
| 222 const Ice::FuncSigType &getFuncSigTypeByID(unsigned ID) { | 235 const Ice::FuncSigType &getFuncSigTypeByID(NaClBcIndexSize_t ID) { |
| 223 const ExtendedType *Ty = getTypeByIDAsKind(ID, ExtendedType::FuncSig); | 236 const ExtendedType *Ty = getTypeByIDAsKind(ID, ExtendedType::FuncSig); |
| 224 if (Ty == nullptr) | 237 if (Ty == nullptr) |
| 225 // Return error recovery value. | 238 // Return error recovery value. |
| 226 return UndefinedFuncSigType; | 239 return UndefinedFuncSigType; |
| 227 return cast<FuncSigExtendedType>(Ty)->getSignature(); | 240 return cast<FuncSigExtendedType>(Ty)->getSignature(); |
| 228 } | 241 } |
| 229 | 242 |
| 230 /// Sets the next function ID to the given LLVM function. | 243 /// Sets the next function ID to the given LLVM function. |
| 231 void setNextFunctionID(Ice::FunctionDeclaration *Fcn) { | 244 void setNextFunctionID(Ice::FunctionDeclaration *Fcn) { |
| 232 FunctionDeclarationList.push_back(Fcn); | 245 FunctionDeclarationList.push_back(Fcn); |
| 233 } | 246 } |
| 234 | 247 |
| 235 /// Returns the value id that should be associated with the the | 248 /// Returns the value id that should be associated with the the |
| 236 /// current function block. Increments internal counters during call | 249 /// current function block. Increments internal counters during call |
| 237 /// so that it will be in correct position for next function block. | 250 /// so that it will be in correct position for next function block. |
| 238 size_t getNextFunctionBlockValueID() { | 251 NaClBcIndexSize_t getNextFunctionBlockValueID() { |
| 239 size_t NumDeclaredFunctions = FunctionDeclarationList.size(); | 252 size_t NumDeclaredFunctions = FunctionDeclarationList.size(); |
| 240 while (NextDefiningFunctionID < NumDeclaredFunctions && | 253 while (NextDefiningFunctionID < NumDeclaredFunctions && |
| 241 FunctionDeclarationList[NextDefiningFunctionID]->isProto()) | 254 FunctionDeclarationList[NextDefiningFunctionID]->isProto()) |
| 242 ++NextDefiningFunctionID; | 255 ++NextDefiningFunctionID; |
| 243 if (NextDefiningFunctionID >= NumDeclaredFunctions) | 256 if (NextDefiningFunctionID >= NumDeclaredFunctions) |
| 244 Fatal("More function blocks than defined function addresses"); | 257 Fatal("More function blocks than defined function addresses"); |
| 245 return NextDefiningFunctionID++; | 258 return NextDefiningFunctionID++; |
| 246 } | 259 } |
| 247 | 260 |
| 248 /// Returns the function associated with ID. | 261 /// Returns the function associated with ID. |
| 249 Ice::FunctionDeclaration *getFunctionByID(unsigned ID) { | 262 Ice::FunctionDeclaration *getFunctionByID(NaClBcIndexSize_t ID) { |
| 250 if (ID < FunctionDeclarationList.size()) | 263 if (ID < FunctionDeclarationList.size()) |
| 251 return FunctionDeclarationList[ID]; | 264 return FunctionDeclarationList[ID]; |
| 252 return reportGetFunctionByIDError(ID); | 265 return reportGetFunctionByIDError(ID); |
| 253 } | 266 } |
| 254 | 267 |
| 255 /// Returns the constant associated with the given global value ID. | 268 /// Returns the constant associated with the given global value ID. |
| 256 Ice::Constant *getGlobalConstantByID(unsigned ID) { | 269 Ice::Constant *getGlobalConstantByID(NaClBcIndexSize_t ID) { |
| 257 assert(ID < ValueIDConstants.size()); | 270 assert(ID < ValueIDConstants.size()); |
| 258 return ValueIDConstants[ID]; | 271 return ValueIDConstants[ID]; |
| 259 } | 272 } |
| 260 | 273 |
| 261 /// Install names for all global values without names. Called after | 274 /// Install names for all global values without names. Called after |
| 262 /// the global value symbol table is processed, but before any | 275 /// the global value symbol table is processed, but before any |
| 263 /// function blocks are processed. | 276 /// function blocks are processed. |
| 264 void installGlobalNames() { | 277 void installGlobalNames() { |
| 265 assert(VariableDeclarations); | 278 assert(VariableDeclarations); |
| 266 installGlobalVarNames(); | 279 installGlobalVarNames(); |
| 267 installFunctionNames(); | 280 installFunctionNames(); |
| 268 } | 281 } |
| 269 | 282 |
| 270 void createValueIDs() { | 283 void createValueIDs() { |
| 271 assert(VariableDeclarations); | 284 assert(VariableDeclarations); |
| 272 ValueIDConstants.reserve(VariableDeclarations->size() + | 285 ValueIDConstants.reserve(VariableDeclarations->size() + |
| 273 FunctionDeclarationList.size()); | 286 FunctionDeclarationList.size()); |
| 274 createValueIDsForFunctions(); | 287 createValueIDsForFunctions(); |
| 275 createValueIDsForGlobalVars(); | 288 createValueIDsForGlobalVars(); |
| 276 } | 289 } |
| 277 | 290 |
| 278 /// Returns the number of function declarations in the bitcode file. | 291 /// Returns the number of function declarations in the bitcode file. |
| 279 unsigned getNumFunctionIDs() const { return FunctionDeclarationList.size(); } | 292 size_t getNumFunctionIDs() const { return FunctionDeclarationList.size(); } |
| 280 | 293 |
| 281 /// Returns the number of global declarations (i.e. IDs) defined in | 294 /// Returns the number of global declarations (i.e. IDs) defined in |
| 282 /// the bitcode file. | 295 /// the bitcode file. |
| 283 unsigned getNumGlobalIDs() const { | 296 size_t getNumGlobalIDs() const { |
| 284 if (VariableDeclarations) { | 297 if (VariableDeclarations) { |
| 285 return FunctionDeclarationList.size() + VariableDeclarations->size(); | 298 return FunctionDeclarationList.size() + VariableDeclarations->size(); |
| 286 } else { | 299 } else { |
| 287 return ValueIDConstants.size(); | 300 return ValueIDConstants.size(); |
| 288 } | 301 } |
| 289 } | 302 } |
| 290 | 303 |
| 291 /// Creates Count global variable declarations. | 304 /// Creates Count global variable declarations. |
| 292 void CreateGlobalVariables(size_t Count) { | 305 void createGlobalVariables(NaClBcIndexSize_t Count) { |
| 293 assert(VariableDeclarations); | 306 assert(VariableDeclarations); |
| 294 assert(VariableDeclarations->empty()); | 307 assert(VariableDeclarations->empty()); |
| 295 for (size_t i = 0; i < Count; ++i) { | 308 for (size_t i = 0; i < Count; ++i) { |
| 296 VariableDeclarations->push_back( | 309 VariableDeclarations->push_back( |
| 297 Ice::VariableDeclaration::create(getTranslator().getContext())); | 310 Ice::VariableDeclaration::create(getTranslator().getContext())); |
| 298 } | 311 } |
| 299 } | 312 } |
| 300 | 313 |
| 301 /// Returns the number of global variable declarations in the | 314 /// Returns the number of global variable declarations in the |
| 302 /// bitcode file. | 315 /// bitcode file. |
| 303 Ice::SizeT getNumGlobalVariables() const { | 316 size_t getNumGlobalVariables() const { |
| 304 if (VariableDeclarations) { | 317 if (VariableDeclarations) { |
| 305 return VariableDeclarations->size(); | 318 return VariableDeclarations->size(); |
| 306 } else { | 319 } else { |
| 307 return ValueIDConstants.size() - FunctionDeclarationList.size(); | 320 return ValueIDConstants.size() - FunctionDeclarationList.size(); |
| 308 } | 321 } |
| 309 } | 322 } |
| 310 | 323 |
| 311 /// Returns the global variable declaration with the given index. | 324 /// Returns the global variable declaration with the given index. |
| 312 Ice::VariableDeclaration *getGlobalVariableByID(unsigned Index) { | 325 Ice::VariableDeclaration *getGlobalVariableByID(NaClBcIndexSize_t Index) { |
| 313 assert(VariableDeclarations); | 326 assert(VariableDeclarations); |
| 314 if (Index < VariableDeclarations->size()) | 327 if (Index < VariableDeclarations->size()) |
| 315 return VariableDeclarations->at(Index); | 328 return VariableDeclarations->at(Index); |
| 316 return reportGetGlobalVariableByIDError(Index); | 329 return reportGetGlobalVariableByIDError(Index); |
| 317 } | 330 } |
| 318 | 331 |
| 319 /// Returns the global declaration (variable or function) with the | 332 /// Returns the global declaration (variable or function) with the |
| 320 /// given Index. | 333 /// given Index. |
| 321 Ice::GlobalDeclaration *getGlobalDeclarationByID(size_t Index) { | 334 Ice::GlobalDeclaration *getGlobalDeclarationByID(NaClBcIndexSize_t Index) { |
| 322 size_t NumFunctionIds = FunctionDeclarationList.size(); | 335 size_t NumFunctionIds = FunctionDeclarationList.size(); |
| 323 if (Index < NumFunctionIds) | 336 if (Index < NumFunctionIds) |
| 324 return getFunctionByID(Index); | 337 return getFunctionByID(Index); |
| 325 else | 338 else |
| 326 return getGlobalVariableByID(Index - NumFunctionIds); | 339 return getGlobalVariableByID(Index - NumFunctionIds); |
| 327 } | 340 } |
| 328 | 341 |
| 329 /// Returns the list of parsed global variable | 342 /// Returns the list of parsed global variable |
| 330 /// declarations. Releases ownership of the current list of global | 343 /// declarations. Releases ownership of the current list of global |
| 331 /// variables. Note: only returns non-null pointer on first | 344 /// variables. Note: only returns non-null pointer on first |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 365 // The block parser currently being applied. Used for error | 378 // The block parser currently being applied. Used for error |
| 366 // reporting. | 379 // reporting. |
| 367 BlockParserBaseClass *BlockParser = nullptr; | 380 BlockParserBaseClass *BlockParser = nullptr; |
| 368 | 381 |
| 369 bool ParseBlock(unsigned BlockID) override; | 382 bool ParseBlock(unsigned BlockID) override; |
| 370 | 383 |
| 371 // Gets extended type associated with the given index, assuming the | 384 // Gets extended type associated with the given index, assuming the |
| 372 // extended type is of the WantedKind. Generates error message if | 385 // extended type is of the WantedKind. Generates error message if |
| 373 // corresponding extended type of WantedKind can't be found, and | 386 // corresponding extended type of WantedKind can't be found, and |
| 374 // returns nullptr. | 387 // returns nullptr. |
| 375 ExtendedType *getTypeByIDAsKind(unsigned ID, | 388 ExtendedType *getTypeByIDAsKind(NaClBcIndexSize_t ID, |
| 376 ExtendedType::TypeKind WantedKind) { | 389 ExtendedType::TypeKind WantedKind) { |
| 377 ExtendedType *Ty = nullptr; | 390 ExtendedType *Ty = nullptr; |
| 378 if (ID < TypeIDValues.size()) { | 391 if (ID < TypeIDValues.size()) { |
| 379 Ty = &TypeIDValues[ID]; | 392 Ty = &TypeIDValues[ID]; |
| 380 if (Ty->getKind() == WantedKind) | 393 if (Ty->getKind() == WantedKind) |
| 381 return Ty; | 394 return Ty; |
| 382 } | 395 } |
| 383 // Generate an error message and set ErrorStatus. | 396 // Generate an error message and set ErrorStatus. |
| 384 this->reportBadTypeIDAs(ID, Ty, WantedKind); | 397 this->reportBadTypeIDAs(ID, Ty, WantedKind); |
| 385 return nullptr; | 398 return nullptr; |
| 386 } | 399 } |
| 387 | 400 |
| 388 // Gives Decl a name if it doesn't already have one. Prefix and | 401 // Gives Decl a name if it doesn't already have one. Prefix and |
| 389 // NameIndex are used to generate the name. NameIndex is | 402 // NameIndex are used to generate the name. NameIndex is |
| 390 // automatically incremented if a new name is created. DeclType is | 403 // automatically incremented if a new name is created. DeclType is |
| 391 // literal text describing the type of name being created. Also | 404 // literal text describing the type of name being created. Also |
| 392 // generates warning if created names may conflict with named | 405 // generates warning if created names may conflict with named |
| 393 // declarations. | 406 // declarations. |
| 394 void installDeclarationName(Ice::GlobalDeclaration *Decl, | 407 void installDeclarationName(Ice::GlobalDeclaration *Decl, |
| 395 const Ice::IceString &Prefix, | 408 const Ice::IceString &Prefix, |
| 396 const char *DeclType, uint32_t &NameIndex) { | 409 const char *DeclType, |
| 410 NaClBcIndexSize_t &NameIndex) { |
| 397 if (Decl->hasName()) { | 411 if (Decl->hasName()) { |
| 398 Translator.checkIfUnnamedNameSafe(Decl->getName(), DeclType, Prefix); | 412 Translator.checkIfUnnamedNameSafe(Decl->getName(), DeclType, Prefix); |
| 399 } else { | 413 } else { |
| 400 Decl->setName(Translator.createUnnamedName(Prefix, NameIndex)); | 414 Decl->setName(Translator.createUnnamedName(Prefix, NameIndex)); |
| 401 ++NameIndex; | 415 ++NameIndex; |
| 402 } | 416 } |
| 403 } | 417 } |
| 404 | 418 |
| 405 // Installs names for global variables without names. | 419 // Installs names for global variables without names. |
| 406 void installGlobalVarNames() { | 420 void installGlobalVarNames() { |
| 407 assert(VariableDeclarations); | 421 assert(VariableDeclarations); |
| 408 const Ice::IceString &GlobalPrefix = | 422 const Ice::IceString &GlobalPrefix = |
| 409 getTranslator().getFlags().getDefaultGlobalPrefix(); | 423 getTranslator().getFlags().getDefaultGlobalPrefix(); |
| 410 if (!GlobalPrefix.empty()) { | 424 if (!GlobalPrefix.empty()) { |
| 411 uint32_t NameIndex = 0; | 425 NaClBcIndexSize_t NameIndex = 0; |
| 412 for (Ice::VariableDeclaration *Var : *VariableDeclarations) { | 426 for (Ice::VariableDeclaration *Var : *VariableDeclarations) { |
| 413 installDeclarationName(Var, GlobalPrefix, "global", NameIndex); | 427 installDeclarationName(Var, GlobalPrefix, "global", NameIndex); |
| 414 } | 428 } |
| 415 } | 429 } |
| 416 } | 430 } |
| 417 | 431 |
| 418 // Installs names for functions without names. | 432 // Installs names for functions without names. |
| 419 void installFunctionNames() { | 433 void installFunctionNames() { |
| 420 const Ice::IceString &FunctionPrefix = | 434 const Ice::IceString &FunctionPrefix = |
| 421 getTranslator().getFlags().getDefaultFunctionPrefix(); | 435 getTranslator().getFlags().getDefaultFunctionPrefix(); |
| 422 if (!FunctionPrefix.empty()) { | 436 if (!FunctionPrefix.empty()) { |
| 423 uint32_t NameIndex = 0; | 437 NaClBcIndexSize_t NameIndex = 0; |
| 424 for (Ice::FunctionDeclaration *Func : FunctionDeclarationList) { | 438 for (Ice::FunctionDeclaration *Func : FunctionDeclarationList) { |
| 425 installDeclarationName(Func, FunctionPrefix, "function", NameIndex); | 439 installDeclarationName(Func, FunctionPrefix, "function", NameIndex); |
| 426 } | 440 } |
| 427 } | 441 } |
| 428 } | 442 } |
| 429 | 443 |
| 430 // Builds a constant symbol named Name, suppressing name mangling if | 444 // Builds a constant symbol named Name, suppressing name mangling if |
| 431 // SuppressMangling. IsExternal is true iff the symbol is external. | 445 // SuppressMangling. IsExternal is true iff the symbol is external. |
| 432 Ice::Constant *getConstantSym(const Ice::IceString &Name, | 446 Ice::Constant *getConstantSym(const Ice::IceString &Name, |
| 433 bool SuppressMangling, bool IsExternal) const { | 447 bool SuppressMangling, bool IsExternal) const { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 458 Ice::Constant *C = nullptr; | 472 Ice::Constant *C = nullptr; |
| 459 if (!isIRGenerationDisabled()) { | 473 if (!isIRGenerationDisabled()) { |
| 460 C = getConstantSym(Decl->getName(), Decl->getSuppressMangling(), | 474 C = getConstantSym(Decl->getName(), Decl->getSuppressMangling(), |
| 461 !Decl->hasInitializer()); | 475 !Decl->hasInitializer()); |
| 462 } | 476 } |
| 463 ValueIDConstants.push_back(C); | 477 ValueIDConstants.push_back(C); |
| 464 } | 478 } |
| 465 } | 479 } |
| 466 | 480 |
| 467 // Reports that type ID is undefined, or not of the WantedType. | 481 // Reports that type ID is undefined, or not of the WantedType. |
| 468 void reportBadTypeIDAs(unsigned ID, const ExtendedType *Ty, | 482 void reportBadTypeIDAs(NaClBcIndexSize_t ID, const ExtendedType *Ty, |
| 469 ExtendedType::TypeKind WantedType); | 483 ExtendedType::TypeKind WantedType); |
| 470 | 484 |
| 471 // Reports that there is no function declaration for ID. Returns an | 485 // Reports that there is no function declaration for ID. Returns an |
| 472 // error recovery value to use. | 486 // error recovery value to use. |
| 473 Ice::FunctionDeclaration *reportGetFunctionByIDError(unsigned ID); | 487 Ice::FunctionDeclaration *reportGetFunctionByIDError(NaClBcIndexSize_t ID); |
| 474 | 488 |
| 475 // Reports that there is not global variable declaration for | 489 // Reports that there is not global variable declaration for |
| 476 // ID. Returns an error recovery value to use. | 490 // ID. Returns an error recovery value to use. |
| 477 Ice::VariableDeclaration *reportGetGlobalVariableByIDError(unsigned Index); | 491 Ice::VariableDeclaration * |
| 492 reportGetGlobalVariableByIDError(NaClBcIndexSize_t Index); |
| 478 | 493 |
| 479 // Reports that there is no corresponding ICE type for LLVMTy, and | 494 // Reports that there is no corresponding ICE type for LLVMTy, and |
| 480 // returns ICE::IceType_void. | 495 // returns Ice::IceType_void. |
| 481 Ice::Type convertToIceTypeError(Type *LLVMTy); | 496 Ice::Type convertToIceTypeError(Type *LLVMTy); |
| 482 }; | 497 }; |
| 483 | 498 |
| 484 bool TopLevelParser::ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit, | 499 bool TopLevelParser::ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit, |
| 485 const std::string &Message) { | 500 const std::string &Message) { |
| 486 ErrorStatus.assign(Ice::EC_Bitcode); | 501 ErrorStatus.assign(Ice::EC_Bitcode); |
| 487 ++NumErrors; | 502 ++NumErrors; |
| 488 Ice::GlobalContext *Context = Translator.getContext(); | 503 Ice::GlobalContext *Context = Translator.getContext(); |
| 489 { // Lock while printing out error message. | 504 { // Lock while printing out error message. |
| 490 Ice::OstreamLocker L(Context); | 505 Ice::OstreamLocker L(Context); |
| 491 raw_ostream &OldErrStream = setErrStream(Context->getStrError()); | 506 raw_ostream &OldErrStream = setErrStream(Context->getStrError()); |
| 492 NaClBitcodeParser::ErrorAt(Level, Bit, Message); | 507 NaClBitcodeParser::ErrorAt(Level, Bit, Message); |
| 493 setErrStream(OldErrStream); | 508 setErrStream(OldErrStream); |
| 494 } | 509 } |
| 495 if (Level >= naclbitc::Error && | 510 if (Level >= naclbitc::Error && |
| 496 !Translator.getFlags().getAllowErrorRecovery()) | 511 !Translator.getFlags().getAllowErrorRecovery()) |
| 497 Fatal(); | 512 Fatal(); |
| 498 return true; | 513 return true; |
| 499 } | 514 } |
| 500 | 515 |
| 501 void TopLevelParser::reportBadTypeIDAs(unsigned ID, const ExtendedType *Ty, | 516 void TopLevelParser::reportBadTypeIDAs(NaClBcIndexSize_t ID, |
| 517 const ExtendedType *Ty, |
| 502 ExtendedType::TypeKind WantedType) { | 518 ExtendedType::TypeKind WantedType) { |
| 503 std::string Buffer; | 519 std::string Buffer; |
| 504 raw_string_ostream StrBuf(Buffer); | 520 raw_string_ostream StrBuf(Buffer); |
| 505 if (Ty == nullptr) { | 521 if (Ty == nullptr) { |
| 506 StrBuf << "Can't find extended type for type id: " << ID; | 522 StrBuf << "Can't find extended type for type id: " << ID; |
| 507 } else { | 523 } else { |
| 508 StrBuf << "Type id " << ID << " not " << WantedType << ". Found: " << *Ty; | 524 StrBuf << "Type id " << ID << " not " << WantedType << ". Found: " << *Ty; |
| 509 } | 525 } |
| 510 BlockError(StrBuf.str()); | 526 blockError(StrBuf.str()); |
| 511 } | 527 } |
| 512 | 528 |
| 513 Ice::FunctionDeclaration * | 529 Ice::FunctionDeclaration * |
| 514 TopLevelParser::reportGetFunctionByIDError(unsigned ID) { | 530 TopLevelParser::reportGetFunctionByIDError(NaClBcIndexSize_t ID) { |
| 515 std::string Buffer; | 531 std::string Buffer; |
| 516 raw_string_ostream StrBuf(Buffer); | 532 raw_string_ostream StrBuf(Buffer); |
| 517 StrBuf << "Function index " << ID | 533 StrBuf << "Function index " << ID |
| 518 << " not allowed. Out of range. Must be less than " | 534 << " not allowed. Out of range. Must be less than " |
| 519 << FunctionDeclarationList.size(); | 535 << FunctionDeclarationList.size(); |
| 520 BlockError(StrBuf.str()); | 536 blockError(StrBuf.str()); |
| 521 // TODO(kschimpf) Remove error recovery once implementation complete. | 537 // TODO(kschimpf) Remove error recovery once implementation complete. |
| 522 if (!FunctionDeclarationList.empty()) | 538 if (!FunctionDeclarationList.empty()) |
| 523 return FunctionDeclarationList[0]; | 539 return FunctionDeclarationList[0]; |
| 524 Fatal(); | 540 Fatal(); |
| 525 } | 541 } |
| 526 | 542 |
| 527 Ice::VariableDeclaration * | 543 Ice::VariableDeclaration * |
| 528 TopLevelParser::reportGetGlobalVariableByIDError(unsigned Index) { | 544 TopLevelParser::reportGetGlobalVariableByIDError(NaClBcIndexSize_t Index) { |
| 529 std::string Buffer; | 545 std::string Buffer; |
| 530 raw_string_ostream StrBuf(Buffer); | 546 raw_string_ostream StrBuf(Buffer); |
| 531 StrBuf << "Global index " << Index | 547 StrBuf << "Global index " << Index |
| 532 << " not allowed. Out of range. Must be less than " | 548 << " not allowed. Out of range. Must be less than " |
| 533 << VariableDeclarations->size(); | 549 << VariableDeclarations->size(); |
| 534 BlockError(StrBuf.str()); | 550 blockError(StrBuf.str()); |
| 535 // TODO(kschimpf) Remove error recovery once implementation complete. | 551 // TODO(kschimpf) Remove error recovery once implementation complete. |
| 536 if (!VariableDeclarations->empty()) | 552 if (!VariableDeclarations->empty()) |
| 537 return VariableDeclarations->at(0); | 553 return VariableDeclarations->at(0); |
| 538 Fatal(); | 554 Fatal(); |
| 539 } | 555 } |
| 540 | 556 |
| 541 Ice::Type TopLevelParser::convertToIceTypeError(Type *LLVMTy) { | 557 Ice::Type TopLevelParser::convertToIceTypeError(Type *LLVMTy) { |
| 542 std::string Buffer; | 558 std::string Buffer; |
| 543 raw_string_ostream StrBuf(Buffer); | 559 raw_string_ostream StrBuf(Buffer); |
| 544 StrBuf << "Invalid LLVM type: " << *LLVMTy; | 560 StrBuf << "Invalid LLVM type: " << *LLVMTy; |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 595 // Default implementation. Reports that block is unknown and skips | 611 // Default implementation. Reports that block is unknown and skips |
| 596 // its contents. | 612 // its contents. |
| 597 bool ParseBlock(unsigned BlockID) override; | 613 bool ParseBlock(unsigned BlockID) override; |
| 598 | 614 |
| 599 // Default implementation. Reports that the record is not | 615 // Default implementation. Reports that the record is not |
| 600 // understood. | 616 // understood. |
| 601 void ProcessRecord() override; | 617 void ProcessRecord() override; |
| 602 | 618 |
| 603 // Checks if the size of the record is Size. Return true if valid. | 619 // Checks if the size of the record is Size. Return true if valid. |
| 604 // Otherwise generates an error and returns false. | 620 // Otherwise generates an error and returns false. |
| 605 bool isValidRecordSize(unsigned Size, const char *RecordName) { | 621 bool isValidRecordSize(size_t Size, const char *RecordName) { |
| 606 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); | 622 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); |
| 607 if (Values.size() == Size) | 623 if (Values.size() == Size) |
| 608 return true; | 624 return true; |
| 609 ReportRecordSizeError(Size, RecordName, nullptr); | 625 reportRecordSizeError(Size, RecordName, nullptr); |
| 610 return false; | 626 return false; |
| 611 } | 627 } |
| 612 | 628 |
| 613 // Checks if the size of the record is at least as large as the | 629 // Checks if the size of the record is at least as large as the |
| 614 // LowerLimit. Returns true if valid. Otherwise generates an error | 630 // LowerLimit. Returns true if valid. Otherwise generates an error |
| 615 // and returns false. | 631 // and returns false. |
| 616 bool isValidRecordSizeAtLeast(unsigned LowerLimit, const char *RecordName) { | 632 bool isValidRecordSizeAtLeast(size_t LowerLimit, const char *RecordName) { |
| 617 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); | 633 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); |
| 618 if (Values.size() >= LowerLimit) | 634 if (Values.size() >= LowerLimit) |
| 619 return true; | 635 return true; |
| 620 ReportRecordSizeError(LowerLimit, RecordName, "at least"); | 636 reportRecordSizeError(LowerLimit, RecordName, "at least"); |
| 621 return false; | 637 return false; |
| 622 } | 638 } |
| 623 | 639 |
| 624 // Checks if the size of the record is no larger than the | 640 // Checks if the size of the record is no larger than the |
| 625 // UpperLimit. Returns true if valid. Otherwise generates an error | 641 // UpperLimit. Returns true if valid. Otherwise generates an error |
| 626 // and returns false. | 642 // and returns false. |
| 627 bool isValidRecordSizeAtMost(unsigned UpperLimit, const char *RecordName) { | 643 bool isValidRecordSizeAtMost(size_t UpperLimit, const char *RecordName) { |
| 628 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); | 644 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); |
| 629 if (Values.size() <= UpperLimit) | 645 if (Values.size() <= UpperLimit) |
| 630 return true; | 646 return true; |
| 631 ReportRecordSizeError(UpperLimit, RecordName, "no more than"); | 647 reportRecordSizeError(UpperLimit, RecordName, "no more than"); |
| 632 return false; | 648 return false; |
| 633 } | 649 } |
| 634 | 650 |
| 635 // Checks if the size of the record is at least as large as the | 651 // Checks if the size of the record is at least as large as the |
| 636 // LowerLimit, and no larger than the UpperLimit. Returns true if | 652 // LowerLimit, and no larger than the UpperLimit. Returns true if |
| 637 // valid. Otherwise generates an error and returns false. | 653 // valid. Otherwise generates an error and returns false. |
| 638 bool isValidRecordSizeInRange(unsigned LowerLimit, unsigned UpperLimit, | 654 bool isValidRecordSizeInRange(size_t LowerLimit, size_t UpperLimit, |
| 639 const char *RecordName) { | 655 const char *RecordName) { |
| 640 return isValidRecordSizeAtLeast(LowerLimit, RecordName) || | 656 return isValidRecordSizeAtLeast(LowerLimit, RecordName) || |
| 641 isValidRecordSizeAtMost(UpperLimit, RecordName); | 657 isValidRecordSizeAtMost(UpperLimit, RecordName); |
| 642 } | 658 } |
| 643 | 659 |
| 644 private: | 660 private: |
| 645 /// Generates a record size error. ExpectedSize is the number | 661 /// Generates a record size error. ExpectedSize is the number |
| 646 /// of elements expected. RecordName is the name of the kind of | 662 /// of elements expected. RecordName is the name of the kind of |
| 647 /// record that has incorrect size. ContextMessage (if not nullptr) | 663 /// record that has incorrect size. ContextMessage (if not nullptr) |
| 648 /// is appended to "record expects" to describe how ExpectedSize | 664 /// is appended to "record expects" to describe how ExpectedSize |
| 649 /// should be interpreted. | 665 /// should be interpreted. |
| 650 void ReportRecordSizeError(unsigned ExpectedSize, const char *RecordName, | 666 void reportRecordSizeError(size_t ExpectedSize, const char *RecordName, |
| 651 const char *ContextMessage); | 667 const char *ContextMessage); |
| 652 }; | 668 }; |
| 653 | 669 |
| 654 bool TopLevelParser::BlockError(const std::string &Message) { | 670 bool TopLevelParser::blockError(const std::string &Message) { |
| 655 if (BlockParser) | 671 if (BlockParser) |
| 656 return BlockParser->Error(Message); | 672 return BlockParser->Error(Message); |
| 657 else | 673 else |
| 658 return Error(Message); | 674 return Error(Message); |
| 659 } | 675 } |
| 660 | 676 |
| 661 // Generates an error Message with the bit address prefixed to it. | 677 // Generates an error Message with the bit address prefixed to it. |
| 662 bool BlockParserBaseClass::ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit, | 678 bool BlockParserBaseClass::ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit, |
| 663 const std::string &Message) { | 679 const std::string &Message) { |
| 664 std::string Buffer; | 680 std::string Buffer; |
| 665 raw_string_ostream StrBuf(Buffer); | 681 raw_string_ostream StrBuf(Buffer); |
| 666 // Note: If dump routines have been turned off, the error messages | 682 // Note: If dump routines have been turned off, the error messages |
| 667 // will not be readable. Hence, replace with simple error. We also | 683 // will not be readable. Hence, replace with simple error. We also |
| 668 // use the simple form for unit tests. | 684 // use the simple form for unit tests. |
| 669 if (getFlags().getGenerateUnitTestMessages()) { | 685 if (getFlags().getGenerateUnitTestMessages()) { |
| 670 StrBuf << "Invalid " << getBlockName() << " record: <" << Record.GetCode(); | 686 StrBuf << "Invalid " << getBlockName() << " record: <" << Record.GetCode(); |
| 671 for (const uint64_t Val : Record.GetValues()) { | 687 for (const uint64_t Val : Record.GetValues()) { |
| 672 StrBuf << " " << Val; | 688 StrBuf << " " << Val; |
| 673 } | 689 } |
| 674 StrBuf << ">"; | 690 StrBuf << ">"; |
| 675 } else { | 691 } else { |
| 676 StrBuf << Message; | 692 StrBuf << Message; |
| 677 } | 693 } |
| 678 return Context->ErrorAt(Level, Bit, StrBuf.str()); | 694 return Context->ErrorAt(Level, Bit, StrBuf.str()); |
| 679 } | 695 } |
| 680 | 696 |
| 681 void BlockParserBaseClass::ReportRecordSizeError(unsigned ExpectedSize, | 697 void BlockParserBaseClass::reportRecordSizeError(size_t ExpectedSize, |
| 682 const char *RecordName, | 698 const char *RecordName, |
| 683 const char *ContextMessage) { | 699 const char *ContextMessage) { |
| 684 std::string Buffer; | 700 std::string Buffer; |
| 685 raw_string_ostream StrBuf(Buffer); | 701 raw_string_ostream StrBuf(Buffer); |
| 686 const char *BlockName = getBlockName(); | 702 const char *BlockName = getBlockName(); |
| 687 const char FirstChar = toupper(*BlockName); | 703 const char FirstChar = toupper(*BlockName); |
| 688 StrBuf << FirstChar << (BlockName + 1) << " " << RecordName | 704 StrBuf << FirstChar << (BlockName + 1) << " " << RecordName |
| 689 << " record expects"; | 705 << " record expects"; |
| 690 if (ContextMessage) | 706 if (ContextMessage) |
| 691 StrBuf << " " << ContextMessage; | 707 StrBuf << " " << ContextMessage; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 721 class TypesParser : public BlockParserBaseClass { | 737 class TypesParser : public BlockParserBaseClass { |
| 722 TypesParser() = delete; | 738 TypesParser() = delete; |
| 723 TypesParser(const TypesParser &) = delete; | 739 TypesParser(const TypesParser &) = delete; |
| 724 TypesParser &operator=(const TypesParser &) = delete; | 740 TypesParser &operator=(const TypesParser &) = delete; |
| 725 | 741 |
| 726 public: | 742 public: |
| 727 TypesParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) | 743 TypesParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) |
| 728 : BlockParserBaseClass(BlockID, EnclosingParser), | 744 : BlockParserBaseClass(BlockID, EnclosingParser), |
| 729 Timer(Ice::TimerStack::TT_parseTypes, getTranslator().getContext()) {} | 745 Timer(Ice::TimerStack::TT_parseTypes, getTranslator().getContext()) {} |
| 730 | 746 |
| 731 ~TypesParser() override = default; | 747 ~TypesParser() override { |
| 748 if (ExpectedNumTypes != Context->getNumTypeIDValues()) { |
| 749 std::string Buffer; |
| 750 raw_string_ostream StrBuf(Buffer); |
| 751 StrBuf << "Types block expected " << ExpectedNumTypes |
| 752 << " types but found: " << NextTypeId; |
| 753 Error(StrBuf.str()); |
| 754 } |
| 755 } |
| 732 | 756 |
| 733 private: | 757 private: |
| 734 Ice::TimerMarker Timer; | 758 Ice::TimerMarker Timer; |
| 735 // The type ID that will be associated with the next type defining | 759 // The type ID that will be associated with the next type defining |
| 736 // record in the types block. | 760 // record in the types block. |
| 737 unsigned NextTypeId = 0; | 761 NaClBcIndexSize_t NextTypeId = 0; |
| 762 |
| 763 // The expected number of types, based on record TYPE_CODE_NUMENTRY. |
| 764 NaClBcIndexSize_t ExpectedNumTypes = 0; |
| 738 | 765 |
| 739 void ProcessRecord() override; | 766 void ProcessRecord() override; |
| 740 | 767 |
| 741 const char *getBlockName() const override { return "type"; } | 768 const char *getBlockName() const override { return "type"; } |
| 742 | 769 |
| 743 void setNextTypeIDAsSimpleType(Ice::Type Ty) { | 770 void setNextTypeIDAsSimpleType(Ice::Type Ty) { |
| 744 Context->getTypeByIDForDefining(NextTypeId++)->setAsSimpleType(Ty); | 771 Context->getTypeByIDForDefining(NextTypeId++)->setAsSimpleType(Ty); |
| 745 } | 772 } |
| 746 }; | 773 }; |
| 747 | 774 |
| 748 void TypesParser::ProcessRecord() { | 775 void TypesParser::ProcessRecord() { |
| 749 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); | 776 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); |
| 750 switch (Record.GetCode()) { | 777 switch (Record.GetCode()) { |
| 751 case naclbitc::TYPE_CODE_NUMENTRY: | 778 case naclbitc::TYPE_CODE_NUMENTRY: { |
| 752 // NUMENTRY: [numentries] | 779 // NUMENTRY: [numentries] |
| 753 if (!isValidRecordSize(1, "count")) | 780 if (!isValidRecordSize(1, "count")) |
| 754 return; | 781 return; |
| 755 Context->resizeTypeIDValues(Values[0]); | 782 uint64_t Size = Values[0]; |
| 783 if (Size > NaClBcIndexSize_t_Max) { |
| 784 std::string Buffer; |
| 785 raw_string_ostream StrBuf(Buffer); |
| 786 StrBuf << "Size to big for count record: " << Size; |
| 787 Error(StrBuf.str()); |
| 788 ExpectedNumTypes = NaClBcIndexSize_t_Max; |
| 789 } |
| 790 // The code double checks that Expected size and the actual size |
| 791 // at the end of the block. To reduce allocations we preallocate |
| 792 // the space. |
| 793 // |
| 794 // However, if the number is large, we suspect that the number |
| 795 // is (possibly) incorrect. In that case, we preallocate a |
| 796 // smaller space. |
| 797 constexpr uint64_t DefaultLargeResizeValue = 1000000; |
| 798 Context->resizeTypeIDValues(std::min(Size, DefaultLargeResizeValue)); |
| 799 ExpectedNumTypes = Size; |
| 756 return; | 800 return; |
| 801 } |
| 757 case naclbitc::TYPE_CODE_VOID: | 802 case naclbitc::TYPE_CODE_VOID: |
| 758 // VOID | 803 // VOID |
| 759 if (!isValidRecordSize(0, "void")) | 804 if (!isValidRecordSize(0, "void")) |
| 760 return; | 805 return; |
| 761 setNextTypeIDAsSimpleType(Ice::IceType_void); | 806 setNextTypeIDAsSimpleType(Ice::IceType_void); |
| 762 return; | 807 return; |
| 763 case naclbitc::TYPE_CODE_FLOAT: | 808 case naclbitc::TYPE_CODE_FLOAT: |
| 764 // FLOAT | 809 // FLOAT |
| 765 if (!isValidRecordSize(0, "float")) | 810 if (!isValidRecordSize(0, "float")) |
| 766 return; | 811 return; |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 863 case naclbitc::TYPE_CODE_FUNCTION: { | 908 case naclbitc::TYPE_CODE_FUNCTION: { |
| 864 // FUNCTION: [vararg, retty, paramty x N] | 909 // FUNCTION: [vararg, retty, paramty x N] |
| 865 if (!isValidRecordSizeAtLeast(2, "signature")) | 910 if (!isValidRecordSizeAtLeast(2, "signature")) |
| 866 return; | 911 return; |
| 867 if (Values[0]) | 912 if (Values[0]) |
| 868 Error("Function type can't define varargs"); | 913 Error("Function type can't define varargs"); |
| 869 ExtendedType *Ty = Context->getTypeByIDForDefining(NextTypeId++); | 914 ExtendedType *Ty = Context->getTypeByIDForDefining(NextTypeId++); |
| 870 Ty->setAsFunctionType(); | 915 Ty->setAsFunctionType(); |
| 871 FuncSigExtendedType *FuncTy = cast<FuncSigExtendedType>(Ty); | 916 FuncSigExtendedType *FuncTy = cast<FuncSigExtendedType>(Ty); |
| 872 FuncTy->setReturnType(Context->getSimpleTypeByID(Values[1])); | 917 FuncTy->setReturnType(Context->getSimpleTypeByID(Values[1])); |
| 873 for (unsigned i = 2, e = Values.size(); i != e; ++i) { | 918 for (size_t i = 2, e = Values.size(); i != e; ++i) { |
| 874 // Check that type void not used as argument type. | 919 // Check that type void not used as argument type. |
| 875 // Note: PNaCl restrictions can't be checked until we | 920 // Note: PNaCl restrictions can't be checked until we |
| 876 // know the name, because we have to check for intrinsic signatures. | 921 // know the name, because we have to check for intrinsic signatures. |
| 877 Ice::Type ArgTy = Context->getSimpleTypeByID(Values[i]); | 922 Ice::Type ArgTy = Context->getSimpleTypeByID(Values[i]); |
| 878 if (ArgTy == Ice::IceType_void) { | 923 if (ArgTy == Ice::IceType_void) { |
| 879 std::string Buffer; | 924 std::string Buffer; |
| 880 raw_string_ostream StrBuf(Buffer); | 925 raw_string_ostream StrBuf(Buffer); |
| 881 StrBuf << "Type for parameter " << (i - 1) | 926 StrBuf << "Type for parameter " << (i - 1) |
| 882 << " not valid. Found: " << ArgTy; | 927 << " not valid. Found: " << ArgTy; |
| 883 // TODO(kschimpf) Remove error recovery once implementation complete. | 928 // TODO(kschimpf) Remove error recovery once implementation complete. |
| (...skipping 26 matching lines...) Expand all Loading... |
| 910 CurGlobalVar(DummyGlobalVar) {} | 955 CurGlobalVar(DummyGlobalVar) {} |
| 911 | 956 |
| 912 ~GlobalsParser() final = default; | 957 ~GlobalsParser() final = default; |
| 913 | 958 |
| 914 const char *getBlockName() const override { return "globals"; } | 959 const char *getBlockName() const override { return "globals"; } |
| 915 | 960 |
| 916 private: | 961 private: |
| 917 Ice::TimerMarker Timer; | 962 Ice::TimerMarker Timer; |
| 918 // Keeps track of how many initializers are expected for the global variable | 963 // Keeps track of how many initializers are expected for the global variable |
| 919 // declaration being built. | 964 // declaration being built. |
| 920 unsigned InitializersNeeded = 0; | 965 NaClBcIndexSize_t InitializersNeeded = 0; |
| 921 | 966 |
| 922 // The index of the next global variable declaration. | 967 // The index of the next global variable declaration. |
| 923 unsigned NextGlobalID = 0; | 968 NaClBcIndexSize_t NextGlobalID = 0; |
| 924 | 969 |
| 925 // Dummy global variable declaration to guarantee CurGlobalVar is | 970 // Dummy global variable declaration to guarantee CurGlobalVar is |
| 926 // always defined (allowing code to not need to check if | 971 // always defined (allowing code to not need to check if |
| 927 // CurGlobalVar is nullptr). | 972 // CurGlobalVar is nullptr). |
| 928 Ice::VariableDeclaration *DummyGlobalVar; | 973 Ice::VariableDeclaration *DummyGlobalVar; |
| 929 | 974 |
| 930 // Holds the current global variable declaration being built. | 975 // Holds the current global variable declaration being built. |
| 931 Ice::VariableDeclaration *CurGlobalVar; | 976 Ice::VariableDeclaration *CurGlobalVar; |
| 932 | 977 |
| 933 void ExitBlock() override { | 978 void ExitBlock() override { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 969 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); | 1014 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); |
| 970 switch (Record.GetCode()) { | 1015 switch (Record.GetCode()) { |
| 971 case naclbitc::GLOBALVAR_COUNT: | 1016 case naclbitc::GLOBALVAR_COUNT: |
| 972 // COUNT: [n] | 1017 // COUNT: [n] |
| 973 if (!isValidRecordSize(1, "count")) | 1018 if (!isValidRecordSize(1, "count")) |
| 974 return; | 1019 return; |
| 975 if (NextGlobalID != Context->getNumGlobalVariables()) { | 1020 if (NextGlobalID != Context->getNumGlobalVariables()) { |
| 976 Error("Globals count record not first in block."); | 1021 Error("Globals count record not first in block."); |
| 977 return; | 1022 return; |
| 978 } | 1023 } |
| 979 Context->CreateGlobalVariables(Values[0]); | 1024 Context->createGlobalVariables(Values[0]); |
| 980 return; | 1025 return; |
| 981 case naclbitc::GLOBALVAR_VAR: { | 1026 case naclbitc::GLOBALVAR_VAR: { |
| 982 // VAR: [align, isconst] | 1027 // VAR: [align, isconst] |
| 983 if (!isValidRecordSize(2, "variable")) | 1028 if (!isValidRecordSize(2, "variable")) |
| 984 return; | 1029 return; |
| 985 verifyNoMissingInitializers(); | 1030 verifyNoMissingInitializers(); |
| 986 if (!isIRGenerationDisabled()) { | 1031 if (!isIRGenerationDisabled()) { |
| 987 InitializersNeeded = 1; | 1032 InitializersNeeded = 1; |
| 988 CurGlobalVar = Context->getGlobalVariableByID(NextGlobalID); | 1033 CurGlobalVar = Context->getGlobalVariableByID(NextGlobalID); |
| 989 CurGlobalVar->setAlignment((1 << Values[0]) >> 1); | 1034 CurGlobalVar->setAlignment((1 << Values[0]) >> 1); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1032 Ice::VariableDeclaration::DataInitializer::create(Values)); | 1077 Ice::VariableDeclaration::DataInitializer::create(Values)); |
| 1033 return; | 1078 return; |
| 1034 } | 1079 } |
| 1035 case naclbitc::GLOBALVAR_RELOC: { | 1080 case naclbitc::GLOBALVAR_RELOC: { |
| 1036 // RELOC: [val, [addend]] | 1081 // RELOC: [val, [addend]] |
| 1037 if (!isValidRecordSizeInRange(1, 2, "reloc")) | 1082 if (!isValidRecordSizeInRange(1, 2, "reloc")) |
| 1038 return; | 1083 return; |
| 1039 if (isIRGenerationDisabled()) | 1084 if (isIRGenerationDisabled()) |
| 1040 return; | 1085 return; |
| 1041 unsigned Index = Values[0]; | 1086 unsigned Index = Values[0]; |
| 1042 Ice::SizeT Offset = 0; | 1087 uint64_t Offset = 0; |
| 1043 if (Values.size() == 2) | 1088 if (Values.size() == 2) { |
| 1044 Offset = Values[1]; | 1089 Offset = Values[1]; |
| 1090 if (Offset > std::numeric_limits<uint32_t>::max()) { |
| 1091 std::string Buffer; |
| 1092 raw_string_ostream StrBuf(Buffer); |
| 1093 StrBuf << "Addend of global reloc record too big: " << Offset; |
| 1094 Error(StrBuf.str()); |
| 1095 } |
| 1096 } |
| 1045 CurGlobalVar->addInitializer( | 1097 CurGlobalVar->addInitializer( |
| 1046 Ice::VariableDeclaration::RelocInitializer::create( | 1098 Ice::VariableDeclaration::RelocInitializer::create( |
| 1047 Context->getGlobalDeclarationByID(Index), Offset)); | 1099 Context->getGlobalDeclarationByID(Index), Offset)); |
| 1048 return; | 1100 return; |
| 1049 } | 1101 } |
| 1050 default: | 1102 default: |
| 1051 BlockParserBaseClass::ProcessRecord(); | 1103 BlockParserBaseClass::ProcessRecord(); |
| 1052 return; | 1104 return; |
| 1053 } | 1105 } |
| 1054 } | 1106 } |
| 1055 | 1107 |
| 1056 /// Base class for parsing a valuesymtab block in the bitcode file. | 1108 /// Base class for parsing a valuesymtab block in the bitcode file. |
| 1057 class ValuesymtabParser : public BlockParserBaseClass { | 1109 class ValuesymtabParser : public BlockParserBaseClass { |
| 1058 ValuesymtabParser() = delete; | 1110 ValuesymtabParser() = delete; |
| 1059 ValuesymtabParser(const ValuesymtabParser &) = delete; | 1111 ValuesymtabParser(const ValuesymtabParser &) = delete; |
| 1060 void operator=(const ValuesymtabParser &) = delete; | 1112 void operator=(const ValuesymtabParser &) = delete; |
| 1061 | 1113 |
| 1062 public: | 1114 public: |
| 1063 ValuesymtabParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) | 1115 ValuesymtabParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) |
| 1064 : BlockParserBaseClass(BlockID, EnclosingParser) {} | 1116 : BlockParserBaseClass(BlockID, EnclosingParser) {} |
| 1065 | 1117 |
| 1066 ~ValuesymtabParser() override = default; | 1118 ~ValuesymtabParser() override = default; |
| 1067 | 1119 |
| 1068 const char *getBlockName() const override { return "valuesymtab"; } | 1120 const char *getBlockName() const override { return "valuesymtab"; } |
| 1069 | 1121 |
| 1070 protected: | 1122 protected: |
| 1071 typedef SmallString<128> StringType; | 1123 typedef SmallString<128> StringType; |
| 1072 | 1124 |
| 1073 // Associates Name with the value defined by the given Index. | 1125 // Associates Name with the value defined by the given Index. |
| 1074 virtual void setValueName(uint64_t Index, StringType &Name) = 0; | 1126 virtual void setValueName(NaClBcIndexSize_t Index, StringType &Name) = 0; |
| 1075 | 1127 |
| 1076 // Associates Name with the value defined by the given Index; | 1128 // Associates Name with the value defined by the given Index; |
| 1077 virtual void setBbName(uint64_t Index, StringType &Name) = 0; | 1129 virtual void setBbName(NaClBcIndexSize_t Index, StringType &Name) = 0; |
| 1078 | 1130 |
| 1079 private: | 1131 private: |
| 1080 void ProcessRecord() override; | 1132 void ProcessRecord() override; |
| 1081 | 1133 |
| 1082 void ConvertToString(StringType &ConvertedName) { | 1134 void convertToString(StringType &ConvertedName) { |
| 1083 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); | 1135 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); |
| 1084 for (size_t i = 1, e = Values.size(); i != e; ++i) { | 1136 for (size_t i = 1, e = Values.size(); i != e; ++i) { |
| 1085 ConvertedName += static_cast<char>(Values[i]); | 1137 ConvertedName += static_cast<char>(Values[i]); |
| 1086 } | 1138 } |
| 1087 } | 1139 } |
| 1088 }; | 1140 }; |
| 1089 | 1141 |
| 1090 void ValuesymtabParser::ProcessRecord() { | 1142 void ValuesymtabParser::ProcessRecord() { |
| 1091 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); | 1143 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); |
| 1092 StringType ConvertedName; | 1144 StringType ConvertedName; |
| 1093 switch (Record.GetCode()) { | 1145 switch (Record.GetCode()) { |
| 1094 case naclbitc::VST_CODE_ENTRY: { | 1146 case naclbitc::VST_CODE_ENTRY: { |
| 1095 // VST_ENTRY: [ValueId, namechar x N] | 1147 // VST_ENTRY: [ValueId, namechar x N] |
| 1096 if (!isValidRecordSizeAtLeast(2, "value entry")) | 1148 if (!isValidRecordSizeAtLeast(2, "value entry")) |
| 1097 return; | 1149 return; |
| 1098 ConvertToString(ConvertedName); | 1150 convertToString(ConvertedName); |
| 1099 setValueName(Values[0], ConvertedName); | 1151 setValueName(Values[0], ConvertedName); |
| 1100 return; | 1152 return; |
| 1101 } | 1153 } |
| 1102 case naclbitc::VST_CODE_BBENTRY: { | 1154 case naclbitc::VST_CODE_BBENTRY: { |
| 1103 // VST_BBENTRY: [BbId, namechar x N] | 1155 // VST_BBENTRY: [BbId, namechar x N] |
| 1104 if (!isValidRecordSizeAtLeast(2, "basic block entry")) | 1156 if (!isValidRecordSizeAtLeast(2, "basic block entry")) |
| 1105 return; | 1157 return; |
| 1106 ConvertToString(ConvertedName); | 1158 convertToString(ConvertedName); |
| 1107 setBbName(Values[0], ConvertedName); | 1159 setBbName(Values[0], ConvertedName); |
| 1108 return; | 1160 return; |
| 1109 } | 1161 } |
| 1110 default: | 1162 default: |
| 1111 break; | 1163 break; |
| 1112 } | 1164 } |
| 1113 // If reached, don't know how to handle record. | 1165 // If reached, don't know how to handle record. |
| 1114 BlockParserBaseClass::ProcessRecord(); | 1166 BlockParserBaseClass::ProcessRecord(); |
| 1115 return; | 1167 return; |
| 1116 } | 1168 } |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1151 if (isIRGenerationDisabled()) { | 1203 if (isIRGenerationDisabled()) { |
| 1152 CurrentNode = nullptr; | 1204 CurrentNode = nullptr; |
| 1153 for (Ice::Type ArgType : Signature.getArgList()) { | 1205 for (Ice::Type ArgType : Signature.getArgList()) { |
| 1154 (void)ArgType; | 1206 (void)ArgType; |
| 1155 setNextLocalInstIndex(nullptr); | 1207 setNextLocalInstIndex(nullptr); |
| 1156 } | 1208 } |
| 1157 } else { | 1209 } else { |
| 1158 Func->setFunctionName(FuncDecl->getName()); | 1210 Func->setFunctionName(FuncDecl->getName()); |
| 1159 Func->setReturnType(Signature.getReturnType()); | 1211 Func->setReturnType(Signature.getReturnType()); |
| 1160 Func->setInternal(FuncDecl->getLinkage() == GlobalValue::InternalLinkage); | 1212 Func->setInternal(FuncDecl->getLinkage() == GlobalValue::InternalLinkage); |
| 1161 CurrentNode = InstallNextBasicBlock(); | 1213 CurrentNode = installNextBasicBlock(); |
| 1162 Func->setEntryNode(CurrentNode); | 1214 Func->setEntryNode(CurrentNode); |
| 1163 for (Ice::Type ArgType : Signature.getArgList()) { | 1215 for (Ice::Type ArgType : Signature.getArgList()) { |
| 1164 Func->addArg(getNextInstVar(ArgType)); | 1216 Func->addArg(getNextInstVar(ArgType)); |
| 1165 } | 1217 } |
| 1166 } | 1218 } |
| 1167 bool ParserResult = ParseThisBlock(); | 1219 bool ParserResult = ParseThisBlock(); |
| 1168 | 1220 |
| 1169 // Temporarily end per-function timing, which will be resumed by | 1221 // Temporarily end per-function timing, which will be resumed by |
| 1170 // the translator function. This is because translation may be | 1222 // the translator function. This is because translation may be |
| 1171 // done asynchronously in a separate thread. | 1223 // done asynchronously in a separate thread. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1186 | 1238 |
| 1187 return ParserResult; | 1239 return ParserResult; |
| 1188 } | 1240 } |
| 1189 | 1241 |
| 1190 ~FunctionParser() final = default; | 1242 ~FunctionParser() final = default; |
| 1191 | 1243 |
| 1192 const char *getBlockName() const override { return "function"; } | 1244 const char *getBlockName() const override { return "function"; } |
| 1193 | 1245 |
| 1194 Ice::Cfg *getFunc() const { return Func.get(); } | 1246 Ice::Cfg *getFunc() const { return Func.get(); } |
| 1195 | 1247 |
| 1196 uint32_t getNumGlobalIDs() const { return CachedNumGlobalValueIDs; } | 1248 size_t getNumGlobalIDs() const { return CachedNumGlobalValueIDs; } |
| 1197 | 1249 |
| 1198 void setNextLocalInstIndex(Ice::Operand *Op) { | 1250 void setNextLocalInstIndex(Ice::Operand *Op) { |
| 1199 setOperand(NextLocalInstIndex++, Op); | 1251 setOperand(NextLocalInstIndex++, Op); |
| 1200 } | 1252 } |
| 1201 | 1253 |
| 1202 // Set the next constant ID to the given constant C. | 1254 // Set the next constant ID to the given constant C. |
| 1203 void setNextConstantID(Ice::Constant *C) { setNextLocalInstIndex(C); } | 1255 void setNextConstantID(Ice::Constant *C) { setNextLocalInstIndex(C); } |
| 1204 | 1256 |
| 1205 // Returns the value referenced by the given value Index. | 1257 // Returns the value referenced by the given value Index. |
| 1206 Ice::Operand *getOperand(uint32_t Index) { | 1258 Ice::Operand *getOperand(NaClBcIndexSize_t Index) { |
| 1207 if (Index < CachedNumGlobalValueIDs) { | 1259 if (Index < CachedNumGlobalValueIDs) { |
| 1208 return Context->getGlobalConstantByID(Index); | 1260 return Context->getGlobalConstantByID(Index); |
| 1209 } | 1261 } |
| 1210 uint32_t LocalIndex = Index - CachedNumGlobalValueIDs; | 1262 NaClBcIndexSize_t LocalIndex = Index - CachedNumGlobalValueIDs; |
| 1211 if (LocalIndex >= LocalOperands.size()) { | 1263 if (LocalIndex >= LocalOperands.size()) { |
| 1212 std::string Buffer; | 1264 std::string Buffer; |
| 1213 raw_string_ostream StrBuf(Buffer); | 1265 raw_string_ostream StrBuf(Buffer); |
| 1214 StrBuf << "Value index " << Index << " not defined!"; | 1266 StrBuf << "Value index " << Index << " not defined!"; |
| 1215 Fatal(StrBuf.str()); | 1267 Fatal(StrBuf.str()); |
| 1216 } | 1268 } |
| 1217 Ice::Operand *Op = LocalOperands[LocalIndex]; | 1269 Ice::Operand *Op = LocalOperands[LocalIndex]; |
| 1218 if (Op == nullptr) { | 1270 if (Op == nullptr) { |
| 1219 if (isIRGenerationDisabled()) | 1271 if (isIRGenerationDisabled()) |
| 1220 return nullptr; | 1272 return nullptr; |
| 1221 std::string Buffer; | 1273 std::string Buffer; |
| 1222 raw_string_ostream StrBuf(Buffer); | 1274 raw_string_ostream StrBuf(Buffer); |
| 1223 StrBuf << "Value index " << Index << " not defined!"; | 1275 StrBuf << "Value index " << Index << " not defined!"; |
| 1224 Fatal(StrBuf.str()); | 1276 Fatal(StrBuf.str()); |
| 1225 } | 1277 } |
| 1226 return Op; | 1278 return Op; |
| 1227 } | 1279 } |
| 1228 | 1280 |
| 1229 private: | 1281 private: |
| 1230 Ice::TimerMarker Timer; | 1282 Ice::TimerMarker Timer; |
| 1231 // The corresponding ICE function defined by the function block. | 1283 // The corresponding ICE function defined by the function block. |
| 1232 std::unique_ptr<Ice::Cfg> Func; | 1284 std::unique_ptr<Ice::Cfg> Func; |
| 1233 // The index to the current basic block being built. | 1285 // The index to the current basic block being built. |
| 1234 uint32_t CurrentBbIndex = 0; | 1286 NaClBcIndexSize_t CurrentBbIndex = 0; |
| 1235 // The basic block being built. | 1287 // The basic block being built. |
| 1236 Ice::CfgNode *CurrentNode = nullptr; | 1288 Ice::CfgNode *CurrentNode = nullptr; |
| 1237 // The ID for the function. | 1289 // The ID for the function. |
| 1238 unsigned FcnId; | 1290 NaClBcIndexSize_t FcnId; |
| 1239 // The corresponding function declaration. | 1291 // The corresponding function declaration. |
| 1240 Ice::FunctionDeclaration *FuncDecl; | 1292 Ice::FunctionDeclaration *FuncDecl; |
| 1241 // Holds the dividing point between local and global absolute value indices. | 1293 // Holds the dividing point between local and global absolute value indices. |
| 1242 uint32_t CachedNumGlobalValueIDs; | 1294 size_t CachedNumGlobalValueIDs; |
| 1243 // Holds operands local to the function block, based on indices | 1295 // Holds operands local to the function block, based on indices |
| 1244 // defined in the bitcode file. | 1296 // defined in the bitcode file. |
| 1245 std::vector<Ice::Operand *> LocalOperands; | 1297 std::vector<Ice::Operand *> LocalOperands; |
| 1246 // Holds the index within LocalOperands corresponding to the next | 1298 // Holds the index within LocalOperands corresponding to the next |
| 1247 // instruction that generates a value. | 1299 // instruction that generates a value. |
| 1248 uint32_t NextLocalInstIndex; | 1300 NaClBcIndexSize_t NextLocalInstIndex; |
| 1249 // True if the last processed instruction was a terminating | 1301 // True if the last processed instruction was a terminating |
| 1250 // instruction. | 1302 // instruction. |
| 1251 bool InstIsTerminating = false; | 1303 bool InstIsTerminating = false; |
| 1252 // Upper limit of alignment power allowed by LLVM | 1304 // Upper limit of alignment power allowed by LLVM |
| 1253 static const uint32_t AlignPowerLimit = 29; | 1305 static const uint32_t AlignPowerLimit = 29; |
| 1254 | 1306 |
| 1255 // Extracts the corresponding Alignment to use, given the AlignPower | 1307 // Extracts the corresponding Alignment to use, given the AlignPower |
| 1256 // (i.e. 2**(AlignPower-1), or 0 if AlignPower == 0). InstName is the | 1308 // (i.e. 2**(AlignPower-1), or 0 if AlignPower == 0). InstName is the |
| 1257 // name of the instruction the alignment appears in. | 1309 // name of the instruction the alignment appears in. |
| 1258 void extractAlignment(const char *InstName, uint32_t AlignPower, | 1310 void extractAlignment(const char *InstName, uint32_t AlignPower, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1270 Alignment = 1; | 1322 Alignment = 1; |
| 1271 } | 1323 } |
| 1272 | 1324 |
| 1273 bool ParseBlock(unsigned BlockID) override; | 1325 bool ParseBlock(unsigned BlockID) override; |
| 1274 | 1326 |
| 1275 void ProcessRecord() override; | 1327 void ProcessRecord() override; |
| 1276 | 1328 |
| 1277 void ExitBlock() override; | 1329 void ExitBlock() override; |
| 1278 | 1330 |
| 1279 // Creates and appends a new basic block to the list of basic blocks. | 1331 // Creates and appends a new basic block to the list of basic blocks. |
| 1280 Ice::CfgNode *InstallNextBasicBlock() { | 1332 Ice::CfgNode *installNextBasicBlock() { |
| 1281 assert(!isIRGenerationDisabled()); | 1333 assert(!isIRGenerationDisabled()); |
| 1282 return Func->makeNode(); | 1334 return Func->makeNode(); |
| 1283 } | 1335 } |
| 1284 | 1336 |
| 1285 // Returns the Index-th basic block in the list of basic blocks. | 1337 // Returns the Index-th basic block in the list of basic blocks. |
| 1286 Ice::CfgNode *getBasicBlock(uint32_t Index) { | 1338 Ice::CfgNode *getBasicBlock(NaClBcIndexSize_t Index) { |
| 1287 assert(!isIRGenerationDisabled()); | 1339 assert(!isIRGenerationDisabled()); |
| 1288 const Ice::NodeList &Nodes = Func->getNodes(); | 1340 const Ice::NodeList &Nodes = Func->getNodes(); |
| 1289 if (Index >= Nodes.size()) { | 1341 if (Index >= Nodes.size()) { |
| 1290 std::string Buffer; | 1342 std::string Buffer; |
| 1291 raw_string_ostream StrBuf(Buffer); | 1343 raw_string_ostream StrBuf(Buffer); |
| 1292 StrBuf << "Reference to basic block " << Index | 1344 StrBuf << "Reference to basic block " << Index |
| 1293 << " not found. Must be less than " << Nodes.size(); | 1345 << " not found. Must be less than " << Nodes.size(); |
| 1294 Error(StrBuf.str()); | 1346 Error(StrBuf.str()); |
| 1295 // TODO(kschimpf) Remove error recovery once implementation complete. | 1347 // TODO(kschimpf) Remove error recovery once implementation complete. |
| 1296 Index = 0; | 1348 Index = 0; |
| 1297 } | 1349 } |
| 1298 return Nodes[Index]; | 1350 return Nodes[Index]; |
| 1299 } | 1351 } |
| 1300 | 1352 |
| 1301 // Returns the Index-th basic block in the list of basic blocks. | 1353 // Returns the Index-th basic block in the list of basic blocks. |
| 1302 // Assumes Index corresponds to a branch instruction. Hence, if | 1354 // Assumes Index corresponds to a branch instruction. Hence, if |
| 1303 // the branch references the entry block, it also generates a | 1355 // the branch references the entry block, it also generates a |
| 1304 // corresponding error. | 1356 // corresponding error. |
| 1305 Ice::CfgNode *getBranchBasicBlock(uint32_t Index) { | 1357 Ice::CfgNode *getBranchBasicBlock(NaClBcIndexSize_t Index) { |
| 1306 assert(!isIRGenerationDisabled()); | 1358 assert(!isIRGenerationDisabled()); |
| 1307 if (Index == 0) { | 1359 if (Index == 0) { |
| 1308 Error("Branch to entry block not allowed"); | 1360 Error("Branch to entry block not allowed"); |
| 1309 // TODO(kschimpf) Remove error recovery once implementation complete. | 1361 // TODO(kschimpf) Remove error recovery once implementation complete. |
| 1310 } | 1362 } |
| 1311 return getBasicBlock(Index); | 1363 return getBasicBlock(Index); |
| 1312 } | 1364 } |
| 1313 | 1365 |
| 1314 // Generate an instruction variable with type Ty. | 1366 // Generate an instruction variable with type Ty. |
| 1315 Ice::Variable *createInstVar(Ice::Type Ty) { | 1367 Ice::Variable *createInstVar(Ice::Type Ty) { |
| 1316 assert(!isIRGenerationDisabled()); | 1368 assert(!isIRGenerationDisabled()); |
| 1317 if (Ty == Ice::IceType_void) { | 1369 if (Ty == Ice::IceType_void) { |
| 1318 Error("Can't define instruction value using type void"); | 1370 Error("Can't define instruction value using type void"); |
| 1319 // Recover since we can't throw an exception. | 1371 // Recover since we can't throw an exception. |
| 1320 Ty = Ice::IceType_i32; | 1372 Ty = Ice::IceType_i32; |
| 1321 } | 1373 } |
| 1322 return Func->makeVariable(Ty); | 1374 return Func->makeVariable(Ty); |
| 1323 } | 1375 } |
| 1324 | 1376 |
| 1325 // Generates the next available local variable using the given type. | 1377 // Generates the next available local variable using the given type. |
| 1326 Ice::Variable *getNextInstVar(Ice::Type Ty) { | 1378 Ice::Variable *getNextInstVar(Ice::Type Ty) { |
| 1327 assert(!isIRGenerationDisabled()); | 1379 assert(!isIRGenerationDisabled()); |
| 1328 assert(NextLocalInstIndex >= CachedNumGlobalValueIDs); | 1380 assert(NextLocalInstIndex >= CachedNumGlobalValueIDs); |
| 1329 // Before creating one, see if a forwardtyperef has already defined it. | 1381 // Before creating one, see if a forwardtyperef has already defined it. |
| 1330 uint32_t LocalIndex = NextLocalInstIndex - CachedNumGlobalValueIDs; | 1382 NaClBcIndexSize_t LocalIndex = NextLocalInstIndex - CachedNumGlobalValueIDs; |
| 1331 if (LocalIndex < LocalOperands.size()) { | 1383 if (LocalIndex < LocalOperands.size()) { |
| 1332 Ice::Operand *Op = LocalOperands[LocalIndex]; | 1384 Ice::Operand *Op = LocalOperands[LocalIndex]; |
| 1333 if (Op != nullptr) { | 1385 if (Op != nullptr) { |
| 1334 if (Ice::Variable *Var = dyn_cast<Ice::Variable>(Op)) { | 1386 if (Ice::Variable *Var = dyn_cast<Ice::Variable>(Op)) { |
| 1335 if (Var->getType() == Ty) { | 1387 if (Var->getType() == Ty) { |
| 1336 ++NextLocalInstIndex; | 1388 ++NextLocalInstIndex; |
| 1337 return Var; | 1389 return Var; |
| 1338 } | 1390 } |
| 1339 } | 1391 } |
| 1340 std::string Buffer; | 1392 std::string Buffer; |
| 1341 raw_string_ostream StrBuf(Buffer); | 1393 raw_string_ostream StrBuf(Buffer); |
| 1342 StrBuf << "Illegal forward referenced instruction (" | 1394 StrBuf << "Illegal forward referenced instruction (" |
| 1343 << NextLocalInstIndex << "): " << *Op; | 1395 << NextLocalInstIndex << "): " << *Op; |
| 1344 Error(StrBuf.str()); | 1396 Error(StrBuf.str()); |
| 1345 // TODO(kschimpf) Remove error recovery once implementation complete. | 1397 // TODO(kschimpf) Remove error recovery once implementation complete. |
| 1346 ++NextLocalInstIndex; | 1398 ++NextLocalInstIndex; |
| 1347 return createInstVar(Ty); | 1399 return createInstVar(Ty); |
| 1348 } | 1400 } |
| 1349 } | 1401 } |
| 1350 Ice::Variable *Var = createInstVar(Ty); | 1402 Ice::Variable *Var = createInstVar(Ty); |
| 1351 setOperand(NextLocalInstIndex++, Var); | 1403 setOperand(NextLocalInstIndex++, Var); |
| 1352 return Var; | 1404 return Var; |
| 1353 } | 1405 } |
| 1354 | 1406 |
| 1355 // Converts a relative index (wrt to BaseIndex) to an absolute value | 1407 // Converts a relative index (wrt to BaseIndex) to an absolute value |
| 1356 // index. | 1408 // index. |
| 1357 uint32_t convertRelativeToAbsIndex(int32_t Id, int32_t BaseIndex) { | 1409 NaClBcIndexSize_t convertRelativeToAbsIndex(NaClRelBcIndexSize_t Id, |
| 1410 NaClRelBcIndexSize_t BaseIndex) { |
| 1358 if (BaseIndex < Id) { | 1411 if (BaseIndex < Id) { |
| 1359 std::string Buffer; | 1412 std::string Buffer; |
| 1360 raw_string_ostream StrBuf(Buffer); | 1413 raw_string_ostream StrBuf(Buffer); |
| 1361 StrBuf << "Invalid relative value id: " << Id | 1414 StrBuf << "Invalid relative value id: " << Id |
| 1362 << " (must be <= " << BaseIndex << ")"; | 1415 << " (must be <= " << BaseIndex << ")"; |
| 1363 Error(StrBuf.str()); | 1416 Error(StrBuf.str()); |
| 1364 // TODO(kschimpf) Remove error recovery once implementation complete. | 1417 // TODO(kschimpf) Remove error recovery once implementation complete. |
| 1365 return 0; | 1418 return 0; |
| 1366 } | 1419 } |
| 1367 return BaseIndex - Id; | 1420 return BaseIndex - Id; |
| 1368 } | 1421 } |
| 1369 | 1422 |
| 1370 // Sets element Index (in the local operands list) to Op. | 1423 // Sets element Index (in the local operands list) to Op. |
| 1371 void setOperand(uint32_t Index, Ice::Operand *Op) { | 1424 void setOperand(NaClBcIndexSize_t Index, Ice::Operand *Op) { |
| 1372 assert(Op || isIRGenerationDisabled()); | 1425 assert(Op || isIRGenerationDisabled()); |
| 1373 // Check if simple push works. | 1426 // Check if simple push works. |
| 1374 uint32_t LocalIndex = Index - CachedNumGlobalValueIDs; | 1427 NaClBcIndexSize_t LocalIndex = Index - CachedNumGlobalValueIDs; |
| 1375 if (LocalIndex == LocalOperands.size()) { | 1428 if (LocalIndex == LocalOperands.size()) { |
| 1376 LocalOperands.push_back(Op); | 1429 LocalOperands.push_back(Op); |
| 1377 return; | 1430 return; |
| 1378 } | 1431 } |
| 1379 | 1432 |
| 1380 // Must be forward reference, expand vector to accommodate. | 1433 // Must be forward reference, expand vector to accommodate. |
| 1381 if (LocalIndex >= LocalOperands.size()) | 1434 if (LocalIndex >= LocalOperands.size()) |
| 1382 LocalOperands.resize(LocalIndex + 1); | 1435 LocalOperands.resize(LocalIndex + 1); |
| 1383 | 1436 |
| 1384 // If element not defined, set it. | 1437 // If element not defined, set it. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1397 raw_string_ostream StrBuf(Buffer); | 1450 raw_string_ostream StrBuf(Buffer); |
| 1398 StrBuf << "Multiple definitions for index " << Index << ": " << *Op | 1451 StrBuf << "Multiple definitions for index " << Index << ": " << *Op |
| 1399 << " and " << *OldOp; | 1452 << " and " << *OldOp; |
| 1400 Error(StrBuf.str()); | 1453 Error(StrBuf.str()); |
| 1401 // TODO(kschimpf) Remove error recovery once implementation complete. | 1454 // TODO(kschimpf) Remove error recovery once implementation complete. |
| 1402 LocalOperands[LocalIndex] = Op; | 1455 LocalOperands[LocalIndex] = Op; |
| 1403 } | 1456 } |
| 1404 | 1457 |
| 1405 // Returns the relative operand (wrt to BaseIndex) referenced by | 1458 // Returns the relative operand (wrt to BaseIndex) referenced by |
| 1406 // the given value Index. | 1459 // the given value Index. |
| 1407 Ice::Operand *getRelativeOperand(int32_t Index, int32_t BaseIndex) { | 1460 Ice::Operand *getRelativeOperand(NaClBcIndexSize_t Index, |
| 1461 NaClBcIndexSize_t BaseIndex) { |
| 1408 return getOperand(convertRelativeToAbsIndex(Index, BaseIndex)); | 1462 return getOperand(convertRelativeToAbsIndex(Index, BaseIndex)); |
| 1409 } | 1463 } |
| 1410 | 1464 |
| 1411 // Returns the absolute index of the next value generating instruction. | 1465 // Returns the absolute index of the next value generating instruction. |
| 1412 uint32_t getNextInstIndex() const { return NextLocalInstIndex; } | 1466 NaClBcIndexSize_t getNextInstIndex() const { return NextLocalInstIndex; } |
| 1413 | 1467 |
| 1414 // Generates type error message for binary operator Op | 1468 // Generates type error message for binary operator Op |
| 1415 // operating on Type OpTy. | 1469 // operating on Type OpTy. |
| 1416 void ReportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy); | 1470 void reportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy); |
| 1417 | 1471 |
| 1418 // Validates if integer logical Op, for type OpTy, is valid. | 1472 // Validates if integer logical Op, for type OpTy, is valid. |
| 1419 // Returns true if valid. Otherwise generates error message and | 1473 // Returns true if valid. Otherwise generates error message and |
| 1420 // returns false. | 1474 // returns false. |
| 1421 bool isValidIntegerLogicalOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) { | 1475 bool isValidIntegerLogicalOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) { |
| 1422 if (Ice::isIntegerType(OpTy)) | 1476 if (Ice::isIntegerType(OpTy)) |
| 1423 return true; | 1477 return true; |
| 1424 ReportInvalidBinaryOp(Op, OpTy); | 1478 reportInvalidBinaryOp(Op, OpTy); |
| 1425 return false; | 1479 return false; |
| 1426 } | 1480 } |
| 1427 | 1481 |
| 1428 // Validates if integer (or vector of integers) arithmetic Op, for type | 1482 // Validates if integer (or vector of integers) arithmetic Op, for type |
| 1429 // OpTy, is valid. Returns true if valid. Otherwise generates | 1483 // OpTy, is valid. Returns true if valid. Otherwise generates |
| 1430 // error message and returns false. | 1484 // error message and returns false. |
| 1431 bool isValidIntegerArithOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) { | 1485 bool isValidIntegerArithOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) { |
| 1432 if (Ice::isIntegerArithmeticType(OpTy)) | 1486 if (Ice::isIntegerArithmeticType(OpTy)) |
| 1433 return true; | 1487 return true; |
| 1434 ReportInvalidBinaryOp(Op, OpTy); | 1488 reportInvalidBinaryOp(Op, OpTy); |
| 1435 return false; | 1489 return false; |
| 1436 } | 1490 } |
| 1437 | 1491 |
| 1438 // Checks if floating arithmetic Op, for type OpTy, is valid. | 1492 // Checks if floating arithmetic Op, for type OpTy, is valid. |
| 1439 // Returns true if valid. Otherwise generates an error message and | 1493 // Returns true if valid. Otherwise generates an error message and |
| 1440 // returns false; | 1494 // returns false; |
| 1441 bool isValidFloatingArithOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) { | 1495 bool isValidFloatingArithOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) { |
| 1442 if (Ice::isFloatingType(OpTy)) | 1496 if (Ice::isFloatingType(OpTy)) |
| 1443 return true; | 1497 return true; |
| 1444 ReportInvalidBinaryOp(Op, OpTy); | 1498 reportInvalidBinaryOp(Op, OpTy); |
| 1445 return false; | 1499 return false; |
| 1446 } | 1500 } |
| 1447 | 1501 |
| 1448 // Checks if the type of operand Op is the valid pointer type, for | 1502 // Checks if the type of operand Op is the valid pointer type, for |
| 1449 // the given InstructionName. Returns true if valid. Otherwise | 1503 // the given InstructionName. Returns true if valid. Otherwise |
| 1450 // generates an error message and returns false. | 1504 // generates an error message and returns false. |
| 1451 bool isValidPointerType(Ice::Operand *Op, const char *InstructionName) { | 1505 bool isValidPointerType(Ice::Operand *Op, const char *InstructionName) { |
| 1452 Ice::Type PtrType = Ice::getPointerType(); | 1506 Ice::Type PtrType = Ice::getPointerType(); |
| 1453 if (Op->getType() == PtrType) | 1507 if (Op->getType() == PtrType) |
| 1454 return true; | 1508 return true; |
| (...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1901 CurrentNode->appendInst(Ice::InstAssign::create(Func.get(), Var, Var)); | 1955 CurrentNode->appendInst(Ice::InstAssign::create(Func.get(), Var, Var)); |
| 1902 } | 1956 } |
| 1903 }; | 1957 }; |
| 1904 | 1958 |
| 1905 void FunctionParser::ExitBlock() { | 1959 void FunctionParser::ExitBlock() { |
| 1906 if (isIRGenerationDisabled()) { | 1960 if (isIRGenerationDisabled()) { |
| 1907 return; | 1961 return; |
| 1908 } | 1962 } |
| 1909 // Before translating, check for blocks without instructions, and | 1963 // Before translating, check for blocks without instructions, and |
| 1910 // insert unreachable. This shouldn't happen, but be safe. | 1964 // insert unreachable. This shouldn't happen, but be safe. |
| 1911 unsigned Index = 0; | 1965 size_t Index = 0; |
| 1912 for (Ice::CfgNode *Node : Func->getNodes()) { | 1966 for (Ice::CfgNode *Node : Func->getNodes()) { |
| 1913 if (Node->getInsts().empty()) { | 1967 if (Node->getInsts().empty()) { |
| 1914 std::string Buffer; | 1968 std::string Buffer; |
| 1915 raw_string_ostream StrBuf(Buffer); | 1969 raw_string_ostream StrBuf(Buffer); |
| 1916 StrBuf << "Basic block " << Index << " contains no instructions"; | 1970 StrBuf << "Basic block " << Index << " contains no instructions"; |
| 1917 Error(StrBuf.str()); | 1971 Error(StrBuf.str()); |
| 1918 // TODO(kschimpf) Remove error recovery once implementation complete. | 1972 // TODO(kschimpf) Remove error recovery once implementation complete. |
| 1919 Node->appendInst(Ice::InstUnreachable::create(Func.get())); | 1973 Node->appendInst(Ice::InstUnreachable::create(Func.get())); |
| 1920 } | 1974 } |
| 1921 ++Index; | 1975 ++Index; |
| 1922 } | 1976 } |
| 1923 Func->computeInOutEdges(); | 1977 Func->computeInOutEdges(); |
| 1924 } | 1978 } |
| 1925 | 1979 |
| 1926 void FunctionParser::ReportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op, | 1980 void FunctionParser::reportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op, |
| 1927 Ice::Type OpTy) { | 1981 Ice::Type OpTy) { |
| 1928 std::string Buffer; | 1982 std::string Buffer; |
| 1929 raw_string_ostream StrBuf(Buffer); | 1983 raw_string_ostream StrBuf(Buffer); |
| 1930 StrBuf << "Invalid operator type for " << Ice::InstArithmetic::getOpName(Op) | 1984 StrBuf << "Invalid operator type for " << Ice::InstArithmetic::getOpName(Op) |
| 1931 << ". Found " << OpTy; | 1985 << ". Found " << OpTy; |
| 1932 Error(StrBuf.str()); | 1986 Error(StrBuf.str()); |
| 1933 } | 1987 } |
| 1934 | 1988 |
| 1935 void FunctionParser::ProcessRecord() { | 1989 void FunctionParser::ProcessRecord() { |
| 1936 // Note: To better separate parse/IR generation times, when IR generation | 1990 // Note: To better separate parse/IR generation times, when IR generation |
| 1937 // is disabled we do the following: | 1991 // is disabled we do the following: |
| 1938 // 1) Delay exiting until after we extract operands. | 1992 // 1) Delay exiting until after we extract operands. |
| 1939 // 2) return before we access operands, since all operands will be a nullptr. | 1993 // 2) return before we access operands, since all operands will be a nullptr. |
| 1940 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); | 1994 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); |
| 1941 if (InstIsTerminating) { | 1995 if (InstIsTerminating) { |
| 1942 InstIsTerminating = false; | 1996 InstIsTerminating = false; |
| 1943 if (!isIRGenerationDisabled()) | 1997 if (!isIRGenerationDisabled()) |
| 1944 CurrentNode = getBasicBlock(++CurrentBbIndex); | 1998 CurrentNode = getBasicBlock(++CurrentBbIndex); |
| 1945 } | 1999 } |
| 1946 // The base index for relative indexing. | 2000 // The base index for relative indexing. |
| 1947 int32_t BaseIndex = getNextInstIndex(); | 2001 NaClBcIndexSize_t BaseIndex = getNextInstIndex(); |
| 1948 switch (Record.GetCode()) { | 2002 switch (Record.GetCode()) { |
| 1949 case naclbitc::FUNC_CODE_DECLAREBLOCKS: { | 2003 case naclbitc::FUNC_CODE_DECLAREBLOCKS: { |
| 1950 // DECLAREBLOCKS: [n] | 2004 // DECLAREBLOCKS: [n] |
| 1951 if (!isValidRecordSize(1, "count")) | 2005 if (!isValidRecordSize(1, "count")) |
| 1952 return; | 2006 return; |
| 1953 uint32_t NumBbs = Values[0]; | 2007 uint64_t NumBbsRaw = Values[0]; |
| 1954 if (NumBbs == 0) { | 2008 if (NumBbsRaw == 0) { |
| 1955 Error("Functions must contain at least one basic block."); | 2009 Error("Functions must contain at least one basic block."); |
| 1956 // TODO(kschimpf) Remove error recovery once implementation complete. | 2010 // TODO(kschimpf) Remove error recovery once implementation complete. |
| 1957 NumBbs = 1; | 2011 NumBbsRaw = 1; |
| 2012 } else if (NumBbsRaw > NaClBcIndexSize_t_Max) { |
| 2013 std::string Buffer; |
| 2014 raw_string_ostream StrBuf(Buffer); |
| 2015 StrBuf << "To many basic blocks specified: " << NumBbsRaw; |
| 2016 Error(StrBuf.str()); |
| 2017 NumBbsRaw = NaClBcIndexSize_t_Max; |
| 1958 } | 2018 } |
| 1959 if (isIRGenerationDisabled()) | 2019 if (isIRGenerationDisabled()) |
| 1960 return; | 2020 return; |
| 1961 if (Func->getNodes().size() != 1) { | 2021 if (Func->getNodes().size() != 1) { |
| 1962 Error("Duplicate function block count record"); | 2022 Error("Duplicate function block count record"); |
| 1963 return; | 2023 return; |
| 1964 } | 2024 } |
| 1965 // Install the basic blocks, skipping bb0 which was created in the | 2025 // Install the basic blocks, skipping bb0 which was created in the |
| 1966 // constructor. | 2026 // constructor. |
| 1967 for (size_t i = 1; i < NumBbs; ++i) | 2027 for (size_t i = 1, NumBbs = NumBbsRaw; i < NumBbs; ++i) |
| 1968 InstallNextBasicBlock(); | 2028 installNextBasicBlock(); |
| 1969 return; | 2029 return; |
| 1970 } | 2030 } |
| 1971 case naclbitc::FUNC_CODE_INST_BINOP: { | 2031 case naclbitc::FUNC_CODE_INST_BINOP: { |
| 1972 // BINOP: [opval, opval, opcode] | 2032 // BINOP: [opval, opval, opcode] |
| 1973 if (!isValidRecordSize(3, "binop")) | 2033 if (!isValidRecordSize(3, "binop")) |
| 1974 return; | 2034 return; |
| 1975 Ice::Operand *Op1 = getRelativeOperand(Values[0], BaseIndex); | 2035 Ice::Operand *Op1 = getRelativeOperand(Values[0], BaseIndex); |
| 1976 Ice::Operand *Op2 = getRelativeOperand(Values[1], BaseIndex); | 2036 Ice::Operand *Op2 = getRelativeOperand(Values[1], BaseIndex); |
| 1977 if (isIRGenerationDisabled()) { | 2037 if (isIRGenerationDisabled()) { |
| 1978 assert(Op1 == nullptr && Op2 == nullptr); | 2038 assert(Op1 == nullptr && Op2 == nullptr); |
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2274 } else if (CondTy != Cond->getType()) { | 2334 } else if (CondTy != Cond->getType()) { |
| 2275 std::string Buffer; | 2335 std::string Buffer; |
| 2276 raw_string_ostream StrBuf(Buffer); | 2336 raw_string_ostream StrBuf(Buffer); |
| 2277 StrBuf << "Case condition expects type " << CondTy | 2337 StrBuf << "Case condition expects type " << CondTy |
| 2278 << ". Found: " << Cond->getType(); | 2338 << ". Found: " << Cond->getType(); |
| 2279 Error(StrBuf.str()); | 2339 Error(StrBuf.str()); |
| 2280 return; | 2340 return; |
| 2281 } | 2341 } |
| 2282 Ice::CfgNode *DefaultLabel = | 2342 Ice::CfgNode *DefaultLabel = |
| 2283 isIRGenDisabled ? nullptr : getBranchBasicBlock(Values[2]); | 2343 isIRGenDisabled ? nullptr : getBranchBasicBlock(Values[2]); |
| 2284 unsigned NumCases = Values[3]; | 2344 uint64_t NumCasesRaw = Values[3]; |
| 2345 if (NumCasesRaw > std::numeric_limits<uint32_t>::max()) { |
| 2346 std::string Buffer; |
| 2347 raw_string_ostream StrBuf(Buffer); |
| 2348 StrBuf << "Too many cases specified in switch: " << NumCasesRaw; |
| 2349 Error(StrBuf.str()); |
| 2350 NumCasesRaw = std::numeric_limits<uint32_t>::max(); |
| 2351 } |
| 2352 uint32_t NumCases = NumCasesRaw; |
| 2285 | 2353 |
| 2286 // Now recognize each of the cases. | 2354 // Now recognize each of the cases. |
| 2287 if (!isValidRecordSize(4 + NumCases * 4, "switch")) | 2355 if (!isValidRecordSize(4 + NumCases * 4, "switch")) |
| 2288 return; | 2356 return; |
| 2289 Ice::InstSwitch *Switch = | 2357 Ice::InstSwitch *Switch = |
| 2290 isIRGenDisabled | 2358 isIRGenDisabled |
| 2291 ? nullptr | 2359 ? nullptr |
| 2292 : Ice::InstSwitch::create(Func.get(), NumCases, Cond, DefaultLabel); | 2360 : Ice::InstSwitch::create(Func.get(), NumCases, Cond, DefaultLabel); |
| 2293 unsigned ValCaseIndex = 4; // index to beginning of case entry. | 2361 unsigned ValCaseIndex = 4; // index to beginning of case entry. |
| 2294 for (unsigned CaseIndex = 0; CaseIndex < NumCases; | 2362 for (uint32_t CaseIndex = 0; CaseIndex < NumCases; |
| 2295 ++CaseIndex, ValCaseIndex += 4) { | 2363 ++CaseIndex, ValCaseIndex += 4) { |
| 2296 if (Values[ValCaseIndex] != 1 || Values[ValCaseIndex + 1] != 1) { | 2364 if (Values[ValCaseIndex] != 1 || Values[ValCaseIndex + 1] != 1) { |
| 2297 std::string Buffer; | 2365 std::string Buffer; |
| 2298 raw_string_ostream StrBuf(Buffer); | 2366 raw_string_ostream StrBuf(Buffer); |
| 2299 StrBuf << "Sequence [1, 1, value, label] expected for case entry " | 2367 StrBuf << "Sequence [1, 1, value, label] expected for case entry " |
| 2300 << "in switch record. (at index" << ValCaseIndex << ")"; | 2368 << "in switch record. (at index" << ValCaseIndex << ")"; |
| 2301 Error(StrBuf.str()); | 2369 Error(StrBuf.str()); |
| 2302 return; | 2370 return; |
| 2303 } | 2371 } |
| 2304 Ice::APInt Value(BitWidth, | 2372 Ice::APInt Value(BitWidth, |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2347 for (unsigned i = 1; i < Values.size(); i += 2) { | 2415 for (unsigned i = 1; i < Values.size(); i += 2) { |
| 2348 assert(getRelativeOperand(NaClDecodeSignRotatedValue(Values[i]), | 2416 assert(getRelativeOperand(NaClDecodeSignRotatedValue(Values[i]), |
| 2349 BaseIndex) == nullptr); | 2417 BaseIndex) == nullptr); |
| 2350 } | 2418 } |
| 2351 setNextLocalInstIndex(nullptr); | 2419 setNextLocalInstIndex(nullptr); |
| 2352 return; | 2420 return; |
| 2353 } | 2421 } |
| 2354 Ice::Variable *Dest = getNextInstVar(Ty); | 2422 Ice::Variable *Dest = getNextInstVar(Ty); |
| 2355 Ice::InstPhi *Phi = | 2423 Ice::InstPhi *Phi = |
| 2356 Ice::InstPhi::create(Func.get(), Values.size() >> 1, Dest); | 2424 Ice::InstPhi::create(Func.get(), Values.size() >> 1, Dest); |
| 2357 for (unsigned i = 1; i < Values.size(); i += 2) { | 2425 for (size_t i = 1; i < Values.size(); i += 2) { |
| 2358 Ice::Operand *Op = | 2426 Ice::Operand *Op = |
| 2359 getRelativeOperand(NaClDecodeSignRotatedValue(Values[i]), BaseIndex); | 2427 getRelativeOperand(NaClDecodeSignRotatedValue(Values[i]), BaseIndex); |
| 2360 if (Op->getType() != Ty) { | 2428 if (Op->getType() != Ty) { |
| 2361 std::string Buffer; | 2429 std::string Buffer; |
| 2362 raw_string_ostream StrBuf(Buffer); | 2430 raw_string_ostream StrBuf(Buffer); |
| 2363 StrBuf << "Value " << *Op << " not type " << Ty | 2431 StrBuf << "Value " << *Op << " not type " << Ty |
| 2364 << " in phi instruction. Found: " << Op->getType(); | 2432 << " in phi instruction. Found: " << Op->getType(); |
| 2365 Error(StrBuf.str()); | 2433 Error(StrBuf.str()); |
| 2366 appendErrorInstruction(Ty); | 2434 appendErrorInstruction(Ty); |
| 2367 return; | 2435 return; |
| (...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2735 Timer(Ice::TimerStack::TT_parseFunctionValuesymtabs, | 2803 Timer(Ice::TimerStack::TT_parseFunctionValuesymtabs, |
| 2736 getTranslator().getContext()) {} | 2804 getTranslator().getContext()) {} |
| 2737 | 2805 |
| 2738 private: | 2806 private: |
| 2739 Ice::TimerMarker Timer; | 2807 Ice::TimerMarker Timer; |
| 2740 // Returns the enclosing function parser. | 2808 // Returns the enclosing function parser. |
| 2741 FunctionParser *getFunctionParser() const { | 2809 FunctionParser *getFunctionParser() const { |
| 2742 return reinterpret_cast<FunctionParser *>(GetEnclosingParser()); | 2810 return reinterpret_cast<FunctionParser *>(GetEnclosingParser()); |
| 2743 } | 2811 } |
| 2744 | 2812 |
| 2745 void setValueName(uint64_t Index, StringType &Name) override; | 2813 void setValueName(NaClBcIndexSize_t Index, StringType &Name) override; |
| 2746 void setBbName(uint64_t Index, StringType &Name) override; | 2814 void setBbName(NaClBcIndexSize_t Index, StringType &Name) override; |
| 2747 | 2815 |
| 2748 // Reports that the assignment of Name to the value associated with | 2816 // Reports that the assignment of Name to the value associated with |
| 2749 // index is not possible, for the given Context. | 2817 // index is not possible, for the given Context. |
| 2750 void reportUnableToAssign(const char *Context, uint64_t Index, | 2818 void reportUnableToAssign(const char *Context, NaClBcIndexSize_t Index, |
| 2751 StringType &Name) { | 2819 StringType &Name) { |
| 2752 std::string Buffer; | 2820 std::string Buffer; |
| 2753 raw_string_ostream StrBuf(Buffer); | 2821 raw_string_ostream StrBuf(Buffer); |
| 2754 StrBuf << "Function-local " << Context << " name '" << Name | 2822 StrBuf << "Function-local " << Context << " name '" << Name |
| 2755 << "' can't be associated with index " << Index; | 2823 << "' can't be associated with index " << Index; |
| 2756 Error(StrBuf.str()); | 2824 Error(StrBuf.str()); |
| 2757 } | 2825 } |
| 2758 }; | 2826 }; |
| 2759 | 2827 |
| 2760 void FunctionValuesymtabParser::setValueName(uint64_t Index, StringType &Name) { | 2828 void FunctionValuesymtabParser::setValueName(NaClBcIndexSize_t Index, |
| 2829 StringType &Name) { |
| 2761 // Note: We check when Index is too small, so that we can error recover | 2830 // Note: We check when Index is too small, so that we can error recover |
| 2762 // (FP->getOperand will create fatal error). | 2831 // (FP->getOperand will create fatal error). |
| 2763 if (Index < getFunctionParser()->getNumGlobalIDs()) { | 2832 if (Index < getFunctionParser()->getNumGlobalIDs()) { |
| 2764 reportUnableToAssign("instruction", Index, Name); | 2833 reportUnableToAssign("instruction", Index, Name); |
| 2765 // TODO(kschimpf) Remove error recovery once implementation complete. | 2834 // TODO(kschimpf) Remove error recovery once implementation complete. |
| 2766 return; | 2835 return; |
| 2767 } | 2836 } |
| 2768 if (isIRGenerationDisabled()) | 2837 if (isIRGenerationDisabled()) |
| 2769 return; | 2838 return; |
| 2770 Ice::Operand *Op = getFunctionParser()->getOperand(Index); | 2839 Ice::Operand *Op = getFunctionParser()->getOperand(Index); |
| 2771 if (Ice::Variable *V = dyn_cast<Ice::Variable>(Op)) { | 2840 if (Ice::Variable *V = dyn_cast<Ice::Variable>(Op)) { |
| 2772 if (ALLOW_DUMP) { | 2841 if (ALLOW_DUMP) { |
| 2773 std::string Nm(Name.data(), Name.size()); | 2842 std::string Nm(Name.data(), Name.size()); |
| 2774 V->setName(getFunctionParser()->getFunc(), Nm); | 2843 V->setName(getFunctionParser()->getFunc(), Nm); |
| 2775 } | 2844 } |
| 2776 } else { | 2845 } else { |
| 2777 reportUnableToAssign("variable", Index, Name); | 2846 reportUnableToAssign("variable", Index, Name); |
| 2778 } | 2847 } |
| 2779 } | 2848 } |
| 2780 | 2849 |
| 2781 void FunctionValuesymtabParser::setBbName(uint64_t Index, StringType &Name) { | 2850 void FunctionValuesymtabParser::setBbName(NaClBcIndexSize_t Index, |
| 2851 StringType &Name) { |
| 2782 if (isIRGenerationDisabled()) | 2852 if (isIRGenerationDisabled()) |
| 2783 return; | 2853 return; |
| 2784 if (Index >= getFunctionParser()->getFunc()->getNumNodes()) { | 2854 if (Index >= getFunctionParser()->getFunc()->getNumNodes()) { |
| 2785 reportUnableToAssign("block", Index, Name); | 2855 reportUnableToAssign("block", Index, Name); |
| 2786 return; | 2856 return; |
| 2787 } | 2857 } |
| 2788 std::string Nm(Name.data(), Name.size()); | 2858 std::string Nm(Name.data(), Name.size()); |
| 2789 if (ALLOW_DUMP) | 2859 if (ALLOW_DUMP) |
| 2790 getFunctionParser()->getFunc()->getNodes()[Index]->setName(Nm); | 2860 getFunctionParser()->getFunc()->getNodes()[Index]->setName(Nm); |
| 2791 } | 2861 } |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2828 private: | 2898 private: |
| 2829 Ice::TimerMarker Timer; | 2899 Ice::TimerMarker Timer; |
| 2830 // True if we have already installed names for unnamed global declarations, | 2900 // True if we have already installed names for unnamed global declarations, |
| 2831 // and have generated global constant initializers. | 2901 // and have generated global constant initializers. |
| 2832 bool GlobalDeclarationNamesAndInitializersInstalled = false; | 2902 bool GlobalDeclarationNamesAndInitializersInstalled = false; |
| 2833 | 2903 |
| 2834 // Generates names for unnamed global addresses (i.e. functions and | 2904 // Generates names for unnamed global addresses (i.e. functions and |
| 2835 // global variables). Then lowers global variable declaration | 2905 // global variables). Then lowers global variable declaration |
| 2836 // initializers to the target. May be called multiple times. Only | 2906 // initializers to the target. May be called multiple times. Only |
| 2837 // the first call will do the installation. | 2907 // the first call will do the installation. |
| 2838 void InstallGlobalNamesAndGlobalVarInitializers() { | 2908 void installGlobalNamesAndGlobalVarInitializers() { |
| 2839 if (!GlobalDeclarationNamesAndInitializersInstalled) { | 2909 if (!GlobalDeclarationNamesAndInitializersInstalled) { |
| 2840 Context->installGlobalNames(); | 2910 Context->installGlobalNames(); |
| 2841 Context->createValueIDs(); | 2911 Context->createValueIDs(); |
| 2842 getTranslator().lowerGlobals(Context->getGlobalVariables()); | 2912 getTranslator().lowerGlobals(Context->getGlobalVariables()); |
| 2843 GlobalDeclarationNamesAndInitializersInstalled = true; | 2913 GlobalDeclarationNamesAndInitializersInstalled = true; |
| 2844 } | 2914 } |
| 2845 } | 2915 } |
| 2846 bool ParseBlock(unsigned BlockID) override; | 2916 bool ParseBlock(unsigned BlockID) override; |
| 2847 | 2917 |
| 2848 void ExitBlock() override { InstallGlobalNamesAndGlobalVarInitializers(); } | 2918 void ExitBlock() override { installGlobalNamesAndGlobalVarInitializers(); } |
| 2849 | 2919 |
| 2850 void ProcessRecord() override; | 2920 void ProcessRecord() override; |
| 2851 }; | 2921 }; |
| 2852 | 2922 |
| 2853 class ModuleValuesymtabParser : public ValuesymtabParser { | 2923 class ModuleValuesymtabParser : public ValuesymtabParser { |
| 2854 ModuleValuesymtabParser() = delete; | 2924 ModuleValuesymtabParser() = delete; |
| 2855 ModuleValuesymtabParser(const ModuleValuesymtabParser &) = delete; | 2925 ModuleValuesymtabParser(const ModuleValuesymtabParser &) = delete; |
| 2856 void operator=(const ModuleValuesymtabParser &) = delete; | 2926 void operator=(const ModuleValuesymtabParser &) = delete; |
| 2857 | 2927 |
| 2858 public: | 2928 public: |
| 2859 ModuleValuesymtabParser(unsigned BlockID, ModuleParser *MP) | 2929 ModuleValuesymtabParser(unsigned BlockID, ModuleParser *MP) |
| 2860 : ValuesymtabParser(BlockID, MP), | 2930 : ValuesymtabParser(BlockID, MP), |
| 2861 Timer(Ice::TimerStack::TT_parseModuleValuesymtabs, | 2931 Timer(Ice::TimerStack::TT_parseModuleValuesymtabs, |
| 2862 getTranslator().getContext()) {} | 2932 getTranslator().getContext()) {} |
| 2863 | 2933 |
| 2864 ~ModuleValuesymtabParser() override = default; | 2934 ~ModuleValuesymtabParser() override = default; |
| 2865 | 2935 |
| 2866 private: | 2936 private: |
| 2867 Ice::TimerMarker Timer; | 2937 Ice::TimerMarker Timer; |
| 2868 void setValueName(uint64_t Index, StringType &Name) override; | 2938 void setValueName(NaClBcIndexSize_t Index, StringType &Name) override; |
| 2869 void setBbName(uint64_t Index, StringType &Name) override; | 2939 void setBbName(NaClBcIndexSize_t Index, StringType &Name) override; |
| 2870 }; | 2940 }; |
| 2871 | 2941 |
| 2872 void ModuleValuesymtabParser::setValueName(uint64_t Index, StringType &Name) { | 2942 void ModuleValuesymtabParser::setValueName(NaClBcIndexSize_t Index, |
| 2943 StringType &Name) { |
| 2873 Context->getGlobalDeclarationByID(Index) | 2944 Context->getGlobalDeclarationByID(Index) |
| 2874 ->setName(StringRef(Name.data(), Name.size())); | 2945 ->setName(StringRef(Name.data(), Name.size())); |
| 2875 } | 2946 } |
| 2876 | 2947 |
| 2877 void ModuleValuesymtabParser::setBbName(uint64_t Index, StringType &Name) { | 2948 void ModuleValuesymtabParser::setBbName(NaClBcIndexSize_t Index, |
| 2949 StringType &Name) { |
| 2878 std::string Buffer; | 2950 std::string Buffer; |
| 2879 raw_string_ostream StrBuf(Buffer); | 2951 raw_string_ostream StrBuf(Buffer); |
| 2880 StrBuf << "Can't define basic block name at global level: '" << Name | 2952 StrBuf << "Can't define basic block name at global level: '" << Name |
| 2881 << "' -> " << Index; | 2953 << "' -> " << Index; |
| 2882 Error(StrBuf.str()); | 2954 Error(StrBuf.str()); |
| 2883 } | 2955 } |
| 2884 | 2956 |
| 2885 bool ModuleParser::ParseBlock(unsigned BlockID) { | 2957 bool ModuleParser::ParseBlock(unsigned BlockID) { |
| 2886 switch (BlockID) { | 2958 switch (BlockID) { |
| 2887 case naclbitc::BLOCKINFO_BLOCK_ID: | 2959 case naclbitc::BLOCKINFO_BLOCK_ID: |
| 2888 return NaClBitcodeParser::ParseBlock(BlockID); | 2960 return NaClBitcodeParser::ParseBlock(BlockID); |
| 2889 case naclbitc::TYPE_BLOCK_ID_NEW: { | 2961 case naclbitc::TYPE_BLOCK_ID_NEW: { |
| 2890 TypesParser Parser(BlockID, this); | 2962 TypesParser Parser(BlockID, this); |
| 2891 return Parser.ParseThisBlock(); | 2963 return Parser.ParseThisBlock(); |
| 2892 } | 2964 } |
| 2893 case naclbitc::GLOBALVAR_BLOCK_ID: { | 2965 case naclbitc::GLOBALVAR_BLOCK_ID: { |
| 2894 GlobalsParser Parser(BlockID, this); | 2966 GlobalsParser Parser(BlockID, this); |
| 2895 return Parser.ParseThisBlock(); | 2967 return Parser.ParseThisBlock(); |
| 2896 } | 2968 } |
| 2897 case naclbitc::VALUE_SYMTAB_BLOCK_ID: { | 2969 case naclbitc::VALUE_SYMTAB_BLOCK_ID: { |
| 2898 ModuleValuesymtabParser Parser(BlockID, this); | 2970 ModuleValuesymtabParser Parser(BlockID, this); |
| 2899 return Parser.ParseThisBlock(); | 2971 return Parser.ParseThisBlock(); |
| 2900 } | 2972 } |
| 2901 case naclbitc::FUNCTION_BLOCK_ID: { | 2973 case naclbitc::FUNCTION_BLOCK_ID: { |
| 2902 InstallGlobalNamesAndGlobalVarInitializers(); | 2974 installGlobalNamesAndGlobalVarInitializers(); |
| 2903 FunctionParser Parser(BlockID, this); | 2975 FunctionParser Parser(BlockID, this); |
| 2904 return Parser.convertFunction(); | 2976 return Parser.convertFunction(); |
| 2905 } | 2977 } |
| 2906 default: | 2978 default: |
| 2907 return BlockParserBaseClass::ParseBlock(BlockID); | 2979 return BlockParserBaseClass::ParseBlock(BlockID); |
| 2908 } | 2980 } |
| 2909 } | 2981 } |
| 2910 | 2982 |
| 2911 void ModuleParser::ProcessRecord() { | 2983 void ModuleParser::ProcessRecord() { |
| 2912 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); | 2984 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); |
| 2913 switch (Record.GetCode()) { | 2985 switch (Record.GetCode()) { |
| 2914 case naclbitc::MODULE_CODE_VERSION: { | 2986 case naclbitc::MODULE_CODE_VERSION: { |
| 2915 // VERSION: [version#] | 2987 // VERSION: [version#] |
| 2916 if (!isValidRecordSize(1, "version")) | 2988 if (!isValidRecordSize(1, "version")) |
| 2917 return; | 2989 return; |
| 2918 unsigned Version = Values[0]; | 2990 uint64_t Version = Values[0]; |
| 2919 if (Version != 1) { | 2991 if (Version != 1) { |
| 2920 std::string Buffer; | 2992 std::string Buffer; |
| 2921 raw_string_ostream StrBuf(Buffer); | 2993 raw_string_ostream StrBuf(Buffer); |
| 2922 StrBuf << "Unknown bitstream version: " << Version; | 2994 StrBuf << "Unknown bitstream version: " << Version; |
| 2923 Error(StrBuf.str()); | 2995 Error(StrBuf.str()); |
| 2924 } | 2996 } |
| 2925 return; | 2997 return; |
| 2926 } | 2998 } |
| 2927 case naclbitc::MODULE_CODE_FUNCTION: { | 2999 case naclbitc::MODULE_CODE_FUNCTION: { |
| 2928 // FUNCTION: [type, callingconv, isproto, linkage] | 3000 // FUNCTION: [type, callingconv, isproto, linkage] |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3024 } | 3096 } |
| 3025 if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) { | 3097 if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) { |
| 3026 ErrStream | 3098 ErrStream |
| 3027 << IRFilename | 3099 << IRFilename |
| 3028 << ": Bitcode stream should be a multiple of 4 bytes in length.\n"; | 3100 << ": Bitcode stream should be a multiple of 4 bytes in length.\n"; |
| 3029 llvm::report_fatal_error("Bitcode stream should be a multiple of 4 bytes"); | 3101 llvm::report_fatal_error("Bitcode stream should be a multiple of 4 bytes"); |
| 3030 } | 3102 } |
| 3031 } | 3103 } |
| 3032 | 3104 |
| 3033 } // end of namespace Ice | 3105 } // end of namespace Ice |
| OLD | NEW |