| OLD | NEW |
| 1 //===- subzero/src/PNaClTranslator.cpp - ICE from bitcode -----------------===// | 1 //===- subzero/src/PNaClTranslator.cpp - ICE from bitcode -----------------===// |
| 2 // | 2 // |
| 3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
| 4 // | 4 // |
| 5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
| 7 // | 7 // |
| 8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
| 9 /// | 9 /// |
| 10 /// \file | 10 /// \file |
| (...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 345 /// ownership of the current list of global variables. Note: only returns | 345 /// ownership of the current list of global variables. Note: only returns |
| 346 /// non-null pointer on first call. All successive calls return a null | 346 /// non-null pointer on first call. All successive calls return a null |
| 347 /// pointer. | 347 /// pointer. |
| 348 std::unique_ptr<Ice::VariableDeclarationList> getGlobalVariables() { | 348 std::unique_ptr<Ice::VariableDeclarationList> getGlobalVariables() { |
| 349 // Before returning, check that ValidIDConstants has already been built. | 349 // Before returning, check that ValidIDConstants has already been built. |
| 350 assert(!VariableDeclarations || | 350 assert(!VariableDeclarations || |
| 351 VariableDeclarations->size() <= ValueIDConstants.size()); | 351 VariableDeclarations->size() <= ValueIDConstants.size()); |
| 352 return std::move(VariableDeclarations); | 352 return std::move(VariableDeclarations); |
| 353 } | 353 } |
| 354 | 354 |
| 355 // Upper limit of alignment power allowed by LLVM |
| 356 static constexpr uint32_t AlignPowerLimit = 29; |
| 357 |
| 358 // Extracts the corresponding Alignment to use, given the AlignPower (i.e. |
| 359 // 2**(AlignPower-1), or 0 if AlignPower == 0). Parser defines the block |
| 360 // context the alignment check appears in, and Prefix defines the context the |
| 361 // alignment appears in. |
| 362 uint32_t extractAlignment(NaClBitcodeParser *Parser, const char *Prefix, |
| 363 uint32_t AlignPower) { |
| 364 if (AlignPower <= AlignPowerLimit + 1) |
| 365 return (1 << AlignPower) >> 1; |
| 366 std::string Buffer; |
| 367 raw_string_ostream StrBuf(Buffer); |
| 368 StrBuf << Prefix << " alignment greater than 2**" << AlignPowerLimit |
| 369 << ". Found: 2**" << (AlignPower - 1); |
| 370 Parser->Error(StrBuf.str()); |
| 371 // Error recover with value that is always acceptable. |
| 372 return 1; |
| 373 } |
| 374 |
| 355 private: | 375 private: |
| 356 // The translator associated with the parser. | 376 // The translator associated with the parser. |
| 357 Ice::Translator &Translator; | 377 Ice::Translator &Translator; |
| 358 // The exit status that should be set to true if an error occurs. | 378 // The exit status that should be set to true if an error occurs. |
| 359 Ice::ErrorCode &ErrorStatus; | 379 Ice::ErrorCode &ErrorStatus; |
| 360 // The number of errors reported. | 380 // The number of errors reported. |
| 361 unsigned NumErrors = 0; | 381 unsigned NumErrors = 0; |
| 362 // The types associated with each type ID. | 382 // The types associated with each type ID. |
| 363 std::vector<ExtendedType> TypeIDValues; | 383 std::vector<ExtendedType> TypeIDValues; |
| 364 // The set of functions (prototype and defined). | 384 // The set of functions (prototype and defined). |
| (...skipping 689 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1054 SpecifiedNumberVars = Values[0]; | 1074 SpecifiedNumberVars = Values[0]; |
| 1055 return; | 1075 return; |
| 1056 case naclbitc::GLOBALVAR_VAR: { | 1076 case naclbitc::GLOBALVAR_VAR: { |
| 1057 // VAR: [align, isconst] | 1077 // VAR: [align, isconst] |
| 1058 if (!isValidRecordSize(2, "variable")) | 1078 if (!isValidRecordSize(2, "variable")) |
| 1059 return; | 1079 return; |
| 1060 verifyNoMissingInitializers(); | 1080 verifyNoMissingInitializers(); |
| 1061 // Always build the global variable, even if IR generation is turned off. | 1081 // Always build the global variable, even if IR generation is turned off. |
| 1062 // This is needed because we need a placeholder in the top-level context | 1082 // This is needed because we need a placeholder in the top-level context |
| 1063 // when no IR is generated. | 1083 // when no IR is generated. |
| 1084 uint32_t Alignment = |
| 1085 Context->extractAlignment(this, "Global variable", Values[0]); |
| 1064 CurGlobalVar = getGlobalVarByID(NextGlobalID); | 1086 CurGlobalVar = getGlobalVarByID(NextGlobalID); |
| 1065 if (!isIRGenerationDisabled()) { | 1087 if (!isIRGenerationDisabled()) { |
| 1066 InitializersNeeded = 1; | 1088 InitializersNeeded = 1; |
| 1067 CurGlobalVar->setAlignment((1 << Values[0]) >> 1); | 1089 CurGlobalVar->setAlignment(Alignment); |
| 1068 CurGlobalVar->setIsConstant(Values[1] != 0); | 1090 CurGlobalVar->setIsConstant(Values[1] != 0); |
| 1069 } | 1091 } |
| 1070 ++NextGlobalID; | 1092 ++NextGlobalID; |
| 1071 return; | 1093 return; |
| 1072 } | 1094 } |
| 1073 case naclbitc::GLOBALVAR_COMPOUND: | 1095 case naclbitc::GLOBALVAR_COMPOUND: |
| 1074 // COMPOUND: [size] | 1096 // COMPOUND: [size] |
| 1075 if (!isValidRecordSize(1, "compound")) | 1097 if (!isValidRecordSize(1, "compound")) |
| 1076 return; | 1098 return; |
| 1077 if (!CurGlobalVar->getInitializers().empty()) { | 1099 if (!CurGlobalVar->getInitializers().empty()) { |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1374 // Holds the dividing point between local and global absolute value indices. | 1396 // Holds the dividing point between local and global absolute value indices. |
| 1375 size_t CachedNumGlobalValueIDs; | 1397 size_t CachedNumGlobalValueIDs; |
| 1376 // Holds operands local to the function block, based on indices defined in | 1398 // Holds operands local to the function block, based on indices defined in |
| 1377 // the bitcode file. | 1399 // the bitcode file. |
| 1378 Ice::OperandList LocalOperands; | 1400 Ice::OperandList LocalOperands; |
| 1379 // Holds the index within LocalOperands corresponding to the next instruction | 1401 // Holds the index within LocalOperands corresponding to the next instruction |
| 1380 // that generates a value. | 1402 // that generates a value. |
| 1381 NaClBcIndexSize_t NextLocalInstIndex; | 1403 NaClBcIndexSize_t NextLocalInstIndex; |
| 1382 // True if the last processed instruction was a terminating instruction. | 1404 // True if the last processed instruction was a terminating instruction. |
| 1383 bool InstIsTerminating = false; | 1405 bool InstIsTerminating = false; |
| 1384 // Upper limit of alignment power allowed by LLVM | |
| 1385 static const uint32_t AlignPowerLimit = 29; | |
| 1386 | |
| 1387 // Extracts the corresponding Alignment to use, given the AlignPower (i.e. | |
| 1388 // 2**(AlignPower-1), or 0 if AlignPower == 0). InstName is the name of the | |
| 1389 // instruction the alignment appears in. | |
| 1390 void extractAlignment(const char *InstName, uint32_t AlignPower, | |
| 1391 uint32_t &Alignment) { | |
| 1392 if (AlignPower <= AlignPowerLimit + 1) { | |
| 1393 Alignment = (1 << AlignPower) >> 1; | |
| 1394 return; | |
| 1395 } | |
| 1396 std::string Buffer; | |
| 1397 raw_string_ostream StrBuf(Buffer); | |
| 1398 StrBuf << InstName << " alignment greater than 2**" << AlignPowerLimit | |
| 1399 << ". Found: 2**" << (AlignPower - 1); | |
| 1400 Error(StrBuf.str()); | |
| 1401 // Error recover with value that is always acceptable. | |
| 1402 Alignment = 1; | |
| 1403 } | |
| 1404 | 1406 |
| 1405 bool ParseBlock(unsigned BlockID) override; | 1407 bool ParseBlock(unsigned BlockID) override; |
| 1406 | 1408 |
| 1407 void ProcessRecord() override; | 1409 void ProcessRecord() override; |
| 1408 | 1410 |
| 1409 void EnterBlock(unsigned NumWords) final { | 1411 void EnterBlock(unsigned NumWords) final { |
| 1410 // Note: Bitstream defines words as 32-bit values. | 1412 // Note: Bitstream defines words as 32-bit values. |
| 1411 NumBytesDefiningFunction = NumWords * sizeof(uint32_t); | 1413 NumBytesDefiningFunction = NumWords * sizeof(uint32_t); |
| 1412 // We know that all records are minimally defined by a two-bit abreviation. | 1414 // We know that all records are minimally defined by a two-bit abreviation. |
| 1413 MaxRecordsInBlock = NumBytesDefiningFunction * (CHAR_BIT >> 1); | 1415 MaxRecordsInBlock = NumBytesDefiningFunction * (CHAR_BIT >> 1); |
| (...skipping 1171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2585 Phi->addArgument(Op, getBasicBlock(Values[i + 1])); | 2587 Phi->addArgument(Op, getBasicBlock(Values[i + 1])); |
| 2586 } | 2588 } |
| 2587 CurrentNode->appendInst(Phi); | 2589 CurrentNode->appendInst(Phi); |
| 2588 return; | 2590 return; |
| 2589 } | 2591 } |
| 2590 case naclbitc::FUNC_CODE_INST_ALLOCA: { | 2592 case naclbitc::FUNC_CODE_INST_ALLOCA: { |
| 2591 // ALLOCA: [Size, align] | 2593 // ALLOCA: [Size, align] |
| 2592 if (!isValidRecordSize(2, "alloca")) | 2594 if (!isValidRecordSize(2, "alloca")) |
| 2593 return; | 2595 return; |
| 2594 Ice::Operand *ByteCount = getRelativeOperand(Values[0], BaseIndex); | 2596 Ice::Operand *ByteCount = getRelativeOperand(Values[0], BaseIndex); |
| 2595 uint32_t Alignment; | 2597 uint32_t Alignment = Context->extractAlignment(this, "Alloca", Values[1]); |
| 2596 extractAlignment("Alloca", Values[1], Alignment); | |
| 2597 if (isIRGenerationDisabled()) { | 2598 if (isIRGenerationDisabled()) { |
| 2598 assert(ByteCount == nullptr); | 2599 assert(ByteCount == nullptr); |
| 2599 setNextLocalInstIndex(nullptr); | 2600 setNextLocalInstIndex(nullptr); |
| 2600 return; | 2601 return; |
| 2601 } | 2602 } |
| 2602 Ice::Type PtrTy = Ice::getPointerType(); | 2603 Ice::Type PtrTy = Ice::getPointerType(); |
| 2603 if (ByteCount->getType() != Ice::IceType_i32) { | 2604 if (ByteCount->getType() != Ice::IceType_i32) { |
| 2604 std::string Buffer; | 2605 std::string Buffer; |
| 2605 raw_string_ostream StrBuf(Buffer); | 2606 raw_string_ostream StrBuf(Buffer); |
| 2606 StrBuf << "Alloca on non-i32 value. Found: " << *ByteCount; | 2607 StrBuf << "Alloca on non-i32 value. Found: " << *ByteCount; |
| 2607 Error(StrBuf.str()); | 2608 Error(StrBuf.str()); |
| 2608 appendErrorInstruction(PtrTy); | 2609 appendErrorInstruction(PtrTy); |
| 2609 return; | 2610 return; |
| 2610 } | 2611 } |
| 2611 CurrentNode->appendInst(Ice::InstAlloca::create( | 2612 CurrentNode->appendInst(Ice::InstAlloca::create( |
| 2612 Func.get(), ByteCount, Alignment, getNextInstVar(PtrTy))); | 2613 Func.get(), ByteCount, Alignment, getNextInstVar(PtrTy))); |
| 2613 return; | 2614 return; |
| 2614 } | 2615 } |
| 2615 case naclbitc::FUNC_CODE_INST_LOAD: { | 2616 case naclbitc::FUNC_CODE_INST_LOAD: { |
| 2616 // LOAD: [address, align, ty] | 2617 // LOAD: [address, align, ty] |
| 2617 if (!isValidRecordSize(3, "load")) | 2618 if (!isValidRecordSize(3, "load")) |
| 2618 return; | 2619 return; |
| 2619 Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex); | 2620 Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex); |
| 2620 Ice::Type Ty = Context->getSimpleTypeByID(Values[2]); | 2621 Ice::Type Ty = Context->getSimpleTypeByID(Values[2]); |
| 2621 uint32_t Alignment; | 2622 uint32_t Alignment = Context->extractAlignment(this, "Load", Values[1]); |
| 2622 extractAlignment("Load", Values[1], Alignment); | |
| 2623 if (isIRGenerationDisabled()) { | 2623 if (isIRGenerationDisabled()) { |
| 2624 assert(Address == nullptr); | 2624 assert(Address == nullptr); |
| 2625 setNextLocalInstIndex(nullptr); | 2625 setNextLocalInstIndex(nullptr); |
| 2626 return; | 2626 return; |
| 2627 } | 2627 } |
| 2628 if (!isValidPointerType(Address, "Load")) { | 2628 if (!isValidPointerType(Address, "Load")) { |
| 2629 appendErrorInstruction(Ty); | 2629 appendErrorInstruction(Ty); |
| 2630 return; | 2630 return; |
| 2631 } | 2631 } |
| 2632 if (!isValidLoadStoreAlignment(Alignment, Ty, "Load")) { | 2632 if (!isValidLoadStoreAlignment(Alignment, Ty, "Load")) { |
| 2633 appendErrorInstruction(Ty); | 2633 appendErrorInstruction(Ty); |
| 2634 return; | 2634 return; |
| 2635 } | 2635 } |
| 2636 CurrentNode->appendInst(Ice::InstLoad::create( | 2636 CurrentNode->appendInst(Ice::InstLoad::create( |
| 2637 Func.get(), getNextInstVar(Ty), Address, Alignment)); | 2637 Func.get(), getNextInstVar(Ty), Address, Alignment)); |
| 2638 return; | 2638 return; |
| 2639 } | 2639 } |
| 2640 case naclbitc::FUNC_CODE_INST_STORE: { | 2640 case naclbitc::FUNC_CODE_INST_STORE: { |
| 2641 // STORE: [address, value, align] | 2641 // STORE: [address, value, align] |
| 2642 if (!isValidRecordSize(3, "store")) | 2642 if (!isValidRecordSize(3, "store")) |
| 2643 return; | 2643 return; |
| 2644 Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex); | 2644 Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex); |
| 2645 Ice::Operand *Value = getRelativeOperand(Values[1], BaseIndex); | 2645 Ice::Operand *Value = getRelativeOperand(Values[1], BaseIndex); |
| 2646 uint32_t Alignment; | 2646 uint32_t Alignment = Context->extractAlignment(this, "Store", Values[2]); |
| 2647 extractAlignment("Store", Values[2], Alignment); | |
| 2648 if (isIRGenerationDisabled()) { | 2647 if (isIRGenerationDisabled()) { |
| 2649 assert(Address == nullptr && Value == nullptr); | 2648 assert(Address == nullptr && Value == nullptr); |
| 2650 return; | 2649 return; |
| 2651 } | 2650 } |
| 2652 if (!isValidPointerType(Address, "Store")) | 2651 if (!isValidPointerType(Address, "Store")) |
| 2653 return; | 2652 return; |
| 2654 if (!isValidLoadStoreAlignment(Alignment, Value->getType(), "Store")) | 2653 if (!isValidLoadStoreAlignment(Alignment, Value->getType(), "Store")) |
| 2655 return; | 2654 return; |
| 2656 CurrentNode->appendInst( | 2655 CurrentNode->appendInst( |
| 2657 Ice::InstStore::create(Func.get(), Value, Address, Alignment)); | 2656 Ice::InstStore::create(Func.get(), Value, Address, Alignment)); |
| (...skipping 624 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3282 raw_string_ostream StrBuf(Buffer); | 3281 raw_string_ostream StrBuf(Buffer); |
| 3283 StrBuf << IRFilename << ": Does not contain a module!"; | 3282 StrBuf << IRFilename << ": Does not contain a module!"; |
| 3284 llvm::report_fatal_error(StrBuf.str()); | 3283 llvm::report_fatal_error(StrBuf.str()); |
| 3285 } | 3284 } |
| 3286 if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) { | 3285 if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) { |
| 3287 llvm::report_fatal_error("Bitcode stream should be a multiple of 4 bytes"); | 3286 llvm::report_fatal_error("Bitcode stream should be a multiple of 4 bytes"); |
| 3288 } | 3287 } |
| 3289 } | 3288 } |
| 3290 | 3289 |
| 3291 } // end of namespace Ice | 3290 } // end of namespace Ice |
| OLD | NEW |