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