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