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